IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> node解密微信小程序用户信息偶然报错 Illegal Buffer -> 正文阅读

[移动开发]node解密微信小程序用户信息偶然报错 Illegal Buffer

为什么会报错?

  • 没有一进入页面就获取code
  • 在点击获取了用户信息 wx.getUserProfile()完成之后才去获取code,导致偶然性解密失败
  • 错误信息
decodeWxUserInfo\WXBizDataCrypt.js:24
 throw new Error('Illegal Buffer err')
 Error: Illegal Buffer err
    at WXBizDataCrypt.decryptData (***\decodeWxUserInfo\WXBizDataCrypt.js:24:11)
    at Request._callback (***\getWxInfo\index.js:21:37)
    at Request.self.callback (***\node_modules\request\request.js:185:22)
    at Request.emit (node:events:390:28)
    at Request.<anonymous> (***\request\request.js:1154:10)
    at Request.emit (node:events:390:28)
    at IncomingMessage.<anonymous> (***\node_modules\request\request.js:1076:12)
    at Object.onceWrapper (node:events:509:28)
    at IncomingMessage.emit (node:events:402:35)
    at endReadableNT (node:internal/streams/readable:1343:12)

错误示例

<view class="login-page-btn" wx:if="{{!hasUserInfo}}">
    <van-button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile" type="info" size="large" round>登录</van-button>
</view>
data: {
    canIUseGetUserProfile: false,
},
onLoad(options) {
    if (wx.getUserProfile) {
        this.setData({
            canIUseGetUserProfile: true
        })
    }
},
getUserProfile(e) {
 // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
  wx.getUserProfile({
      desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
          console.log('userInfo', res);
          this.login(res)
      },
      fail: _ => {
          wx.showToast({
              title: '用户信息获取失败',
              icon: "error",
              duration: 1000 * 2
          })
      }
  })
},
login(event) {
    wx.showLoading({
        title: '登陆中~',
    })
    const iv = event.iv;
    const encryptedData = event.encryptedData;
    
    this.getCode(iv, encryptedData)
},
getCode(iv, encryptedData) {
    // 登录
    wx.login({
        success: res => {
            wx.$http.post('getUserInfo', {
                code: res.code,
                iv,
                encryptedData
            }).then(res => {
                this.getUserInfo(res)
            }).catch(_ => {
                wx.hideLoading()
                wx.showToast({
                    title: '获取code失败,请重新登录',
                    icon: "none",
                    duration: 1000 * 3
                })
            })
            // 发送 res.code 到后台换取 openId, sessionKey, unionId
        }
    })
},
getUserInfo(res) {
    console.log('iv, encryptedData', res);
    wx.hideLoading()
    wx.showToast({
        title: res.msg,
        icon: "success",
        duration: 1000 * 1.5
    })
},
  • 这样操作的结果:

    • 起初正常

      • 在这里插入图片描述
    • 过一段时间再次点击会报node解密失败

      • 在这里插入图片描述
  • 这样的问题出现在wx.login需要在执行wx.getUserProfile() 之前拿到,具体原因未明

正确示例

  • 进入页面拿到code,存起来
  • 点击获取个人信息按钮,成功之后调用this.login()
  • 然后拿到code,iv,encryptedData发送给后端。
  • node通过code去换到openid,session_key,
  • node再通过session_key,iv,encryptedData去拿到加密后的用户信息进行解密
  • 如果code过期了直接返回
  • 否则进行解密,解密之后返回给前端
data: {
    canIUseGetUserProfile: false,
},
onLoad(options) {
    this.getCode();
    if (wx.getUserProfile) {
        this.setData({
            canIUseGetUserProfile: true
        })
    }
},
getCode() {
    // 登录
    wx.login({
        success: res => {
            this.setData({
                code: res.code
            })
        }
    })
},
getUserProfile(e) {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
    wx.getUserProfile({
        desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
        success: (res) => {
            console.log('userInfo', res);
            this.login(res)
        },
        fail: _ => {
            wx.showToast({
                title: '用户信息获取失败',
                icon: "error",
                duration: 1000 * 2
            })
        }
    })
},
login(event) {
    wx.showLoading({
        title: '登陆中~',
    })
    const iv = event.iv;
    const encryptedData = event.encryptedData;

    wx.$http.post('getUserInfo', {
        code: this.data.code,
        iv,
        encryptedData
    }).then(res => {
        this.getUserInfo(res)
    }).catch(err => {
        wx.hideLoading()
        console.log(err);
        wx.showToast({
            title: err,
            icon: "none",
            duration: 1000 * 3
        })
    })
},
getUserInfo(res) {
    console.log('iv, encryptedData', res);
    wx.hideLoading()
    if (res.code === 40163) {
        wx.showToast({
            title: 'code过期,请重新登录!',
            icon: "none",
            duration: 1000 * 1.5
        })
        this.getCode() // 重新获取一次后,再次点击的时候可以用最新的code
    } else {
        wx.showToast({
            title: res.msg,
            icon: "success",
            duration: 1000 * 1.5
        })
    }
},
  • index.js
    import {getUserInfo } from './getWxInfo'
    const express = require('express');
    const router = express.Router();
    router.post('/getUserInfo', (req, res) => {
        const params = req.body;
        getWxInfo.getUserInfo(params.code, params.iv, params.encryptedData).then(child => {
            console.log('child', child);
            res.send({
                code: 200,
                msg: '登录成功',
                body: child
            });
        }).catch(err => {
            res.send({
                code: err.errcode,
                msg: err.errmsg,
                body: null
            })
            console.log({ err });
        })
    });
    
  • getWxInfo/index.js
    const request = require('request')
    const WXBizDataCrypt = require('../decodeWxUserInfo/WXBizDataCrypt')
    
    
    const APP_URL = 'https://api.weixin.qq.com/sns/jscode2session'
    const APP_ID = 'wx276*********2'   //自己小程序的app id ,在公众开发者后台可以看到
    const APP_SECRET = 'd37**************104'  //自己小程序的app secrect,在公众开发者后台可以看到
    exports.getUserInfo = async (code, iv, encryptedData) => {
        // let code=code //解析前端传递过来的参数js_code
        return new Promise((resolve, reject) => {
             request(`${APP_URL}?appid=${APP_ID}&secret=${APP_SECRET}&js_code=${code}&grant_type=authorization_code`, function (err, response, body) {
                if (!err && response.statusCode == 200) {
                    let JSONBody = JSON.parse(body)
                    if (!JSONBody.errcode) {
                        let session_key = JSONBody.session_key
                        const pc = new WXBizDataCrypt(APP_ID, session_key)
                        const data = pc.decryptData(encryptedData, iv)
                        resolve(data)
                    } else {
                        reject(JSONBody)
                    }
                } else {
                    console.log('errs');
                    reject(err)
                }
            })
        })
    }
    
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:22:54  更:2022-04-04 12:22:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 20:30:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码