天天看点

微信小程序登入流程微信小程序登入流程

微信小程序登入流程

前言:openid与unionid

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 系统繁忙,此时请开发者稍候再试
请求成功
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"
  }
})