二、解决登录session_key 的问题

二、解决登录session_key 的问题

目录一、登录会话密钥 session_key 有效性二、解决登录session_key 的问题案例:解决session_key 过期问题,发送个人信息后台解密后端解密信息,存入数据库mysql数据库存表情设置三、后端,如何解析wx.getUserInfor中的用户信息。用户信息官方文档数据加密官方文档

一、登录会话密钥 session_key 有效性

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html

开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。

wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 auth.code2Session 接口更新服务器存储的 session_key。

微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序,session_key 有效期越长。

开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免小程序反复执行登录流程。

当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。

二、解决登录session_key 的问题

通过wx.checkSession判断是否过期。

第一步:在生命周期中onLaunch调用一次写的登录方法

第二步:在其他地方通过wx.checkSession判断是否过期,如果过期再次调用登录方法,更新session_key

案例:解决session_key 过期问题,发送个人信息后台解密

# app.js中:

//app.js

App({

/*

当小程序初始话完成,会触发onlaunch(全局只触发一次)

*/

onLaunch: function () {

// 登录

this.my_login()

},

my_login: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/"

}

})

# 页面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就是用户的信息

// 将数据发送后端

wx.request({

// 发送iv,encryptedData

url: app.globalData.baseurl + "getinfo/",

data:{

iv:res.iv,

encryptedData: res.encryptedData,

token:wx.getStorageSync("token")

},

method:"POST",

success:(e) =>{

console.log('后台返回的数据',e)

}

})

},

})

// 判断是否过期

wx.checkSession({

success() {

//session_key 未过期,并且在本生命周期一直有效

},

fail() {

// session_key 已经失效,需要重新执行登录流程

app.my_login() // 重新登录,更新session_key

wx.getUserInfo({

success: (res) => {

console.log("res啦啦啦", res) //这个res就是用户的信息

// 将数据发送后端

wx.request({

// 发送iv,encryptedData

url: 'url',

})

},

})

}

})

}

}

})

}

后端解密信息,存入数据库

# 登录:略

# 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'],

}

# 把用户信息存入数据库

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": "缺少参数"})

# 检测对字典排序

# 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数据库存表情设置

1.mysql数据库类型

2.配置:默认是utf8,3个字节。表情是4个字节,需要设置:'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,所以用必须是登入状态。

2 但是session_key是有有效期。而且session_key的有效期,不是一个固定值,他是通过用户行为来决定,session_key的有效期时间。

3 但是我们可以通过wx.checkSession来判断有没有过期。

4 保证session_key没有过期的情况下。我们将iv,encryptedData,token(登入凭证)发送到后端.

5 后端使用官方提供的sdk,进行解密。

6 解密成功以后保存到数据,数据库的字符集一定要是utf8mb4,才能保存表情包

如官方的sdk没有Crypto包用下面的方法解决:

pip install pycryptodome

用户信息官方文档

https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserInfo.html

数据加密官方文档

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html

相关推荐

【最便宜台式电脑】最便宜台式电脑报价及图片大全
365bet手机版客户端

【最便宜台式电脑】最便宜台式电脑报价及图片大全

📅 07-17 👁️ 6227
Raspberry Pi
best365从哪能进去

Raspberry Pi

📅 10-28 👁️ 8294
任天堂官方解决Switch手柄断线、失灵问题的方案
365bet手机版客户端

任天堂官方解决Switch手柄断线、失灵问题的方案

📅 07-16 👁️ 4058