目录
  • 一、登录会话密钥 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数据库存表情设置

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

        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

        以上就是微信小程序登录会话密钥session失效解决方案的详细内容,更多关于微信小程序登录会话密钥session的资料请关注其它相关文章!

        声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。