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

目录
  • 一、登录会话密钥 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

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

(0)

相关推荐

  • 微信小程序开发一键登录 获取session_key和openid实例

    微信小程序开发一键登录 获取session_key和openid实例 思来想去不愿自己的微信小程序是个单机版本.自己又不会写后台.现在借助leancloud可以实现微信小程序一键登录功能.尝试后,做笔记. 第一步:下载av-weapp.js,放到utils下. 第二步:使用 const AV = require('../../utils/av-weapp.js');路径根据具体情况而定. 第三步:做初始化. AV.init({ appId: 'EJx0NSfY********-gzGzoHsz'

  • 微信小程序简洁登录页面的实现(附源码)

    目录 1.上图 2.用户不存在 3.上代码 1.上图 2.用户不存在 3.上代码 3.1login.wxml <view class="v1" style="height:{{clientHeight?clientHeight+'px':'auto'}}"> <!-- v2父容器 子view使用绝对布局 --> <view class="v2"> <view class="dltext"

  • 微信小程序保持session会话的方法

    一般我们web网站都会有cookie来保存session ID,将用户和服务器保持在一次会话中,但是很遗憾,微信小程序不支持cookie,他的每一次请求就是一次会话,这样就会产生一个问题,每次请求都需要确定当前的用户是谁,但是我们又不能在每次请求的数据中携带用户的信息,这样是不安全的.今天就介绍两种方式来实现保持会话. 第一种:客户端保存session ID 1.通过wx.login接口获取 code,将code传递到后台(一般后台都有shiro或者Spring security这种过滤器,该方

  • 微信小程序实现短信登录的实战

    目录 1.界面效果预览 2.uView安装 3.uView配置 3.1 main.js中引入 3.2 uni.scss中引入 3.3 App.vue中引入 3.4 pages.json中配置 4.短信登录界面 5.点击获取验证码接口 项目要求增加短信登录及人脸识别登录功能,下面我们来实现下短信登录功能 1.界面效果预览 2.uView安装 uView官网:https://www.uviewui.com 以npm安装为例,执行:npm install uview-ui即可 3.uView配置 3.

  • 微信小程序sessionid不一致问题解决

    问题 由于小程序端两次请求的 sessionid 不一致, 导致后端无法取得 session 解决办法 在登录时获取sessionid //第一次请求登录接口时保存到sessionid中 success: function (res) { wx.hideLoading(); wx.removeStorageSync('sessionid');//每次登录时清楚缓存 if (res.data.code == "0000") { if (res.data.data.roleList[0].

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

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

  • 微信小程序登录session的使用

    获取微信小程序登录的session,整个过程如下: 第一步:小程序取得要往服务端传的 js_code App({ onLaunch: function() { wx.login({ success: function(res) { if (res.code) { //TODO } else { console.log('获取用户登录态失败!' + res.errMsg) } } }); } }) 第二步:服务器接收js_code,然后调用微信接口验证,获取session_key 接口调用地址:h

  • java实现微信小程序登录态维护的示例代码

    相信不少喜欢开发的朋友都已经知道微信小程序是个什么物种了,楼主也是从小程序内测期间就开始关注,并且也写过几个已经上线的微信小程序.但是基本上都是写的纯前端,最近楼主从后端到前端写一个完整的小程序项目,中间碰到了一些问题,楼主会找一些个人觉得有学习价值的点不定时的拿出来跟大家分享,希望对你有一些帮助. 本次就从最基本的微信小程序登录态维护开始吧.小程序官方api文档里面有对登录态的一个完整的解释,并且有相关的代码.想看详情,可以出门右转:https://mp.weixin.qq.com/debug

  • 微信小程序登录态控制深入分析

    微信小程序登录态控制深入分析 最近微信小程序终于开放了个人注册,我当然不能浪费这个炫技的好机会,"菲麦日程"小程序正在全力推进中,尽请期待~~ 在登录态控制中,摸索尝试了小一阵子,特此分享 一.微信建议的登录态控制 说明: 1)小程序内通过wx.login接口获得code 2)将code传入后台,后台对微信服务器发起一个https请求换取openid.session_key 3)后台生成一个自身的3rd_session(以此为key值保持openid和session_key),返回给前

  • 微信小程序 登录实例详解

    微信小程序登录 一. 小程序不支持cookie会话 1. 通过传递与检验3rd_session来保持会话 2. 3rd_session可以执行'`head -n 80 /dev/urandom | tr -dc A-Za-z0-9 | head -c 168`该命令生成 3. 使用Redis或者数据库存储session 4. 生成的3rd_session发送给客户端,写入storage 5. 客户端的每次请求必须带上3rd_session 二.加密数据解码 1. $iv,$code是被加密过的数

  • 微信小程序登录数据解密及状态维持实例详解

    本文实例讲述了微信小程序登录数据解密及状态维持.分享给大家供大家参考,具体如下: 学习过小程序的朋友应该知道,在小程序中是不支持cookie的,借助小程序中的缓存我们也可以存储一些信息,但是对于一些比较重要的信息,我们需要通过登录状态维持来保存,同时,为了安全起见,用户的敏感信息,也是需要加密在网络上传输的. 前台,service.封装了http请求,同时封装了getSession(通过code获取服务器生成的session).getUserInfo(获取用户信息).getDecryptionD

  • 微信小程序登录态和检验注册过没的app.js写法

    0.可参考的官方页面 获取登录凭证:https://developers.weixin.qq.com/miniprogram/dev/api/wx.login.html 检查登录态是否过期: https://developers.weixin.qq.com/miniprogram/dev/api/wx.checkSession.html 备注:你要明白什么是登录态:这里的登录态是微信小程序自己的登录态,我们可以再自己写个登录页面作为自己的登录态,不过为了用户体验良好我直接以微信登录态做为自己的登

  • Java中基于Shiro,JWT实现微信小程序登录完整例子及实现过程

    小程序官方流程图如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html : 本文是对接微信小程序自定义登录的一个完整例子实现 ,技术栈为 : SpringBoot+Shiro+JWT+JPA+Redis. 如果对该例子比较感兴趣或者觉得言语表达比较啰嗦,可查看完整的项目地址 : https://github.com/EalenXie/shiro-jwt-applet

  • Python Flask微信小程序登录流程及登录api实现代码

    一.先来看看效果 接口请求返回的数据: 二.官方登录流程图 三.小程序登录流程梳理: 1.小程序端调用wx.login 2.判断用户是否授权 3.小程序端访问 wx.getUserInfo 4.小程序端js代码: wx.login({ success: resp => { // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log(resp); var that = this; // 获取用户信息 wx.getSetting({ su

  • Spring Boot 2结合Spring security + JWT实现微信小程序登录

    项目源码:https://gitee.com/tanwubo/jwt-spring-security-demo 登录 通过自定义的WxAppletAuthenticationFilter替换默认的UsernamePasswordAuthenticationFilter,在UsernamePasswordAuthenticationFilter中可任意定制自己的登录方式. 用户认证 需要结合JWT来实现用户认证,第一步登录成功后如何颁发token. public class CustomAuthe

随机推荐