为什么会报错?
- 没有一进入页面就获取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({
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
})
})
}
})
},
getUserInfo(res) {
console.log('iv, encryptedData', res);
wx.hideLoading()
wx.showToast({
title: res.msg,
icon: "success",
duration: 1000 * 1.5
})
},
正确示例
- 进入页面拿到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({
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()
} 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'
const APP_SECRET = 'd37**************104'
exports.getUserInfo = async (code, iv, encryptedData) => {
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)
}
})
})
}
|