天天看點

微信小程式登入流程微信小程式登入流程

微信小程式登入流程

前言: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"
  }
})