微信小程序登入流程
微信小程序登入流程
前言:
openid:是用单个微信应用表示用户的唯一标识。亚洲:饼哥小程序上openid :123,那该用户再张成的小程序上他的opendid不是123,是其他任意一个值,上面的意思:同一用户再不用不同应用上的openid不同,但是再同一应用上唯一。
场景: 假设你们公司有2个小程序。但是你们老板想把用户做统一处理。比如新用户登入任意一个小程序,就发送发送礼包。但是只要再一个小程序上另过了,就不能再另一个上面领取。
unionnid:一个用户在多个小程序有唯一的标识
1、小程序端执行wx.login()获取code 2、将code通过wx.request发送到后端,后端调用auth.code2Session接口得到openid和session_key 3、后端得到openid和session_key,进行存储,并自定义登入状态,我们生成一个key与openid和session_key相绑定。key相当于token把token返回到小程序中 4、小程序端保存token,然后下次请求如果需要登录状态,就把token带上。
一.首先前端先传code去后端
App({ onLaunch: function () { let that = this // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log(res.code) wx.request({ url: that.globalData.baseurl+"/login/", data:{"code":res.code}, method:"POST", success(e){ console.log(e) } }) } }), globalData: { userInfo: null, baseurl:"http://127.0.0.1:8000" } })
二.后端接受到请求中的code
class Login(APIView): def post(self,request): code = request.data.get('code') print(code,type(code)) #061j8by70sZPPC1yynx70kCuy70j8byp <class 'str'>
三.后端获得code之后向微信官方发起请求获得相关参数
发起的链接
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
请求参数
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
appid | string | 是 | 小程序 appId | |
secret | string | 是 | 小程序 appSecret | |
js_code | string | 是 | 登录时获取的 code | |
grant_type | string | 是 | 授权类型,此处只需填写 authorization_code |
返回值
返回的 JSON 数据包
属性 | 类型 | 说明 |
---|---|---|
openid | string | 用户唯一标识 |
session_key | string | 会话密钥 |
unionid | string | 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。 |
errcode | number | 错误码 |
errmsg | string | 错误信息 |
errcode 的合法值
值 | 说明 | 最低版本 |
---|---|---|
-1 | 系统繁忙,此时请开发者稍候再试 | |
0 | 请求成功 | |
40029 | code 无效 | |
45011 | 频率限制,每个用户每分钟100次 |
接着上述我们对于路径进行拼接成他需要的内容
wx_login.py
from . import settings import requests def get_login_info(code): # https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code code_url = settings.code2Session.format(settings.AppId,settings.AppSecret,code) response = requests.get(code_url) json_response = response.json() print("json_response",json_response) if json_response.get("session_key"): return json_response else: return False
settings.py
AppId="wxc35e10f7101fafa" AppSecret="1479996b514da2428a89352717ae7c" code2Session="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"
四.加密并返回给前端一个标识方便后续操作
from rest_framework.views import APIView from rest_framework.response import Response from app01.wx import wx_login from django.core.cache import cache from .models import Wxuser import time import hashlib class Login(APIView): def post(self,request): code = request.data.get('code') print(code,type(code)) #061j8by70sZPPC1yynx70kCuy70j8byp <class 'str'> if not code: return Response({"status":1,"msg":"缺少参数"}) else: user_data = wx_login.get_login_info(code) # print(user_data) if user_data: val = user_data['session_key'] + "&" + user_data['openid'] md5 = hashlib.md5() md5.update(str(time.clock()).encode("utf-8")) md5.update(user_data["session_key"].encode("utf-8")) # 生成一个唯一标识的key,用来给前台 key = md5.hexdigest() # 设置缓存减少数据库的压力 cache.set(key,val) has_user = Wxuser.objects.filter(openid=user_data['openid']).first() if not has_user: Wxuser.objects.create(openid=user_data['openid']) #将唯一标识存储到数据库 return Response({ "status":0, "msg":"ok", "data":{"token":key} }) else: return Response({"status":2,"msg":"缺少参数"})
五.前端在前没有任何问题的情况下对于标识信息进行接收
App({ onLaunch: function () { let that = this // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log(res.code) wx.request({ url: that.globalData.baseurl+"/login/", data:{"code":res.code}, method:"POST", success(e){ wx.setStorageSync("token", e.data.data.token) } }) } }), globalData: { userInfo: null, baseurl:"http://127.0.0.1:8000" } })