微信小程序登錄會話密鑰session失效解決方案
一、登錄會話密鑰 session_key 有效性
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
開發(fā)者如果遇到因為 session_key 不正確而校驗簽名失敗或解密失敗,請關(guān)注下面幾個與 session_key 有關(guān)的注意事項。
- wx.login 調(diào)用時,用戶的 session_key 可能會被更新而致使舊 session_key 失效(刷新機制存在最短周期,如果同一個用戶短時間內(nèi)多次調(diào)用 wx.login,并非每次調(diào)用都導致 session_key 刷新)。開發(fā)者應該在明確需要重新登錄時才調(diào)用 wx.login,及時通過 auth.code2Session 接口更新服務(wù)器存儲的 session_key。
- 微信不會把 session_key 的有效期告知開發(fā)者。我們會根據(jù)用戶使用小程序的行為對 session_key 進行續(xù)期。用戶越頻繁使用小程序,session_key 有效期越長。
- 開發(fā)者在 session_key 失效時,可以通過重新執(zhí)行登錄流程獲取有效的 session_key。使用接口 wx.checkSession可以校驗 session_key 是否有效,從而避免小程序反復執(zhí)行登錄流程。
- 當開發(fā)者在實現(xiàn)自定義登錄態(tài)時,可以考慮以 session_key 有效期作為自身登錄態(tài)有效期,也可以實現(xiàn)自定義的時效性策略。
二、解決登錄session_key 的問題
通過wx.checkSession判斷是否過期。
第一步:在生命周期中onLaunch調(diào)用一次寫的登錄方法
第二步:在其他地方通過wx.checkSession判斷是否過期,如果過期再次調(diào)用登錄方法,更新session_key
案例:解決session_key 過期問題,發(fā)送個人信息后臺解密
# app.js中:
//app.js
App({
/*
當小程序初始話完成,會觸發(fā)onlaunch(全局只觸發(fā)一次)
*/
onLaunch: function () {
// 登錄
this.my_login()
},
my_login:function(){
let that = this
wx.login({
success: res => {
// 發(fā)送 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/"
}
})
# 頁面js中:
// 先拿到app全局對象
const app = getApp()
user1:function (e) {
wx.getSetting({
success(res) {
if (res.authSetting['scope.userInfo']) {
wx.getUserInfo({
success: (res) => {
console.log("res",res) //這個res就是用戶的信息
// 將數(shù)據(jù)發(fā)送后端
wx.request({
// 發(fā)送iv,encryptedData
url: app.globalData.baseurl + "getinfo/",
data:{
iv:res.iv,
encryptedData: res.encryptedData,
token:wx.getStorageSync("token")
},
method:"POST",
success:(e) =>{
console.log('后臺返回的數(shù)據(jù)',e)
}
})
},
})
// 判斷是否過期
wx.checkSession({
success() {
//session_key 未過期,并且在本生命周期一直有效
},
fail() {
// session_key 已經(jīng)失效,需要重新執(zhí)行登錄流程
app.my_login() // 重新登錄,更新session_key
wx.getUserInfo({
success: (res) => {
console.log("res啦啦啦", res) //這個res就是用戶的信息
// 將數(shù)據(jù)發(fā)送后端
wx.request({
// 發(fā)送iv,encryptedData
url: 'url',
})
},
})
}
})
}
}
})
}
后端解密信息,存入數(shù)據(jù)庫
# 登錄:略
# urls.py
path('getinfo/', user.Info.as_view()),
# user.py
from django.core.cache import cache
from api.models import Wxuser
from api.wx import WXBizDataCrypt
from api.my_ser import wx_user_ser
from rest_framework.response import Response
class Info(APIView):
def post(self, request):
param = request.data
if param['iv'] and param.get("token") and param.get("encryptedData"):
iv = param['iv']
encryptedData = param.get("encryptedData")
session_key_openid = cache.get(param.get("token"))
if session_key_openid:
sessionKey, openid = session_key_openid.split("&")
# 解密
user_info = WXBizDataCrypt.WXBizDataCrypt.get_info(sessionKey, encryptedData, iv)
print('user_info', user_info)
save_data = {
"name": user_info['nickName'],
"avatar": user_info['avatarUrl'],
"language": user_info['language'],
"province": user_info['province'],
"city": user_info['city'],
"country": user_info['country'],
}
# 把用戶信息存入數(shù)據(jù)庫
Wxuser.objects.filter(openid=openid).update(**save_data)
# 測試:把童虎信息返回給前臺
user = Wxuser.objects.filter(openid=openid).first()
user = wx_user_ser(instance=user, many=False).data
return Response({
"status": 0,
"msg": "ok",
"data": user
})
else:
return Response({"code": 2, "msg": "無效的token"})
else:
return Response({"code": 1, "msg": "缺少參數(shù)"})
# 檢測對字典排序
# WXBizDataCrypt文件,下載的解密,然后二次封裝的
import base64
import json
from Crypto.Cipher import AES
from api.wx import settings
class WXBizDataCrypt:
def __init__(self, appId, sessionKey):
self.appId = appId
self.sessionKey = sessionKey
def decrypt(self, encryptedData, iv):
# base64 decode
sessionKey = base64.b64decode(self.sessionKey)
encryptedData = base64.b64decode(encryptedData)
iv = base64.b64decode(iv)
cipher = AES.new(sessionKey, AES.MODE_CBC, iv)
decrypted = json.loads(self._unpad(cipher.decrypt(encryptedData)))
if decrypted['watermark']['appid'] != self.appId:
raise Exception('Invalid Buffer')
return decrypted
def _unpad(self, s):
return s[:-ord(s[len(s)-1:])]
@classmethod
def get_info(cls,sessionKey,encryptedData,iv):
# appId = settings.AppId
# sessionKey = sessionKey
# encryptedData = encryptedData
# iv = iv
#
# # 實例化這個類 WXBizDataCrypt
# pc = cls(appId, sessionKey)
# return pc.decrypt(encryptedData, iv)
# 簡化為:
return cls(settings.AppId, sessionKey).decrypt(encryptedData, iv)
mysql數(shù)據(jù)庫存表情設(shè)置

1.mysql數(shù)據(jù)庫類型
2.配置:默認是utf8,3個字節(jié)。表情是4個字節(jié)
需要設(shè)置:'OPTIONS': {'charset': 'utf8mb4'}
import pymysql
pymysql.install_as_MySQLdb()
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'python13',
'USER': 'root',
'PASSWORD': '123',
'HOST': 'localhost',
'PORT': 3306,
'OPTIONS': {'charset': 'utf8mb4'},
}
}
三、后端,如何解析wx.getUserInfor中的用戶信息。
1 我們用encryptedData和iv,進行解密,必須要用到session_key,所以用必須是登入狀態(tài)。
2 但是session_key是有有效期。而且session_key的有效期,不是一個固定值,他是通過用戶行為來決定,session_key的有效期時間。
3 但是我們可以通過wx.checkSession來判斷有沒有過期。
4 保證session_key沒有過期的情況下。我們將iv,encryptedData,token(登入憑證)發(fā)送到后端.
5 后端使用官方提供的sdk,進行解密。
6 解密成功以后保存到數(shù)據(jù),數(shù)據(jù)庫的字符集一定要是utf8mb4,才能保存表情包
如官方的sdk沒有Crypto包用下面的方法解決:
pip install pycryptodome
用戶信息官方文檔
https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserInfo.html
數(shù)據(jù)加密官方文檔
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
以上就是微信小程序登錄會話密鑰session失效解決方案的詳細內(nèi)容,更多關(guān)于微信小程序登錄會話密鑰session的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于javascript實現(xiàn)彩票隨機數(shù)生成(簡單版)
這篇文章主要介紹了基于javascript實現(xiàn)彩票隨機數(shù)生成的相關(guān)資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-01-01
使用webpack/gulp構(gòu)建TypeScript項目的方法示例
這篇文章主要介紹了使用webpack/gulp構(gòu)建TypeScript項目的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12

