小程序在拉取用户授权的时候获取用户手机号,前端获取后后端解密就可以存到数据库了。
1.getPhoneNumber这个组件通过button来实现(别的标签无效)。将button中的open-type=“getPhoneNumber”,并且绑定bindgetphonenumber事件获取回调。
2.在使用这个组件之前必须先调用login接口,如果没有调用login点击button时会提示先调用login。
App({
onLaunch: function () {
wx.login({
success: function (res) {
if (res.code) {
//发起网络请求
console.log(res.code)
} else {
console.log('获取用户登录态失败!' + res.errMsg)
}
}
});
}
})
3.通过bindgetphonenumber绑定的事件来获取回调。回调的参数有三个,
errMsg:用户点击取消或授权的信息回调。
iv:加密算法的初始向量(如果用户没有同意授权则为undefined)。
encryptedData: 用户信息的加密数据(如果用户没有同意授权同样返回undefined)
getPhoneNumber(e) {
let CONST = app.$.CONST
let appid = CONST.APPID
let secret = CONST.APPSECRET
let grant_type = 'authorization_code'
let encryptedData = e.detail.encryptedData
let iv= e.detail.iv
wx.login({
success(res){
wx.request({
url: 'https://api.weixin.qq.com/sns/jscode2session?appid=wx8493c38c2f678a82&secret=57bfc41d2101a3a517b2bd7dec399803&js_code=' + res.code +'&grant_type=authorization_code',
success(r) {
let session_key = r.data.session_key
request({
url: “后端处理解密的API”,
data:{
id:app.$.info.id,//这个是当前用户的ID,便于存到数据库
session_key,
encryptedData,
iv,
appId:appid
},
success:res=>{
console.log(res)
}
})
}
})
}
})
},
4.后端解密API(js),按官方文档来
const crypto = require('crypto')
module.exports = async(ctx, next) => {
let {
iv,
encryptedData,
session_key,
appId,
id
} = ctx.request.body
function WXBizDataCrypt(appId, session_key) {
this.appId = appId
this.session_key = session_key
}
WXBizDataCrypt.prototype.decryptData = function(encryptedData, iv) {
// base64 decode
var session_key = new Buffer(this.session_key, 'base64')
encryptedData = new Buffer(encryptedData, 'base64')
iv = new Buffer(iv, 'base64')
try {
// 解密
var decipher = crypto.createDecipheriv('aes-128-cbc', session_key, iv)
// 设置自动 padding 为 true,删除填充补位
decipher.setAutoPadding(true)
var decoded = decipher.update(encryptedData, 'binary', 'utf8')
decoded += decipher.final('utf8')
decoded = JSON.parse(decoded)
} catch (err) {
throw new Error('Illegal Buffer')
}
if (decoded.watermark.appid !== this.appId) {
throw new Error('Illegal Buffer')
}
return decoded
}
let pc = new WXBizDataCrypt(appId, session_key)
let data = pc.decryptData(encryptedData, iv)
return ctx.db('User')
.update({
phoneNum: data.phoneNumber
}).where({
id
}).then(r =>{
console.log(r)
ctx.body = data
})
.catch(err=>{
console.error(err)
})
}
5.至此返回的数据就是用户手机号了,中间的业务逻辑还是去看下官方文档的,这里说的不好,只是大概的逻辑是这样。