千家信息网

微信小程序登录会话密钥session失效怎么解决

发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,本篇内容主要讲解"微信小程序登录会话密钥session失效怎么解决",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"微信小程序登录会话密钥session失效怎
千家信息网最后更新 2024年11月11日微信小程序登录会话密钥session失效怎么解决

本篇内容主要讲解"微信小程序登录会话密钥session失效怎么解决",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"微信小程序登录会话密钥session失效怎么解决"吧!

    一、登录会话密钥 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.jsApp({  /*    当小程序初始话完成,会触发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.pypath('getinfo/', user.Info.as_view()),# user.pyfrom django.core.cache import cachefrom api.models import Wxuserfrom api.wx import WXBizDataCryptfrom api.my_ser import wx_user_serfrom rest_framework.response import Responseclass 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 base64import jsonfrom Crypto.Cipher import AESfrom api.wx import settingsclass 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 pymysqlpymysql.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

    到此,相信大家对"微信小程序登录会话密钥session失效怎么解决"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    0