微信小程式登入流程
前言: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"
}
})