小程序通过云函数获得用户手机号码?
思路解析,
了解了小程序的加密方式,我们就可以自己去解密我们需要的信息。如:最困住我们的用户手机号码?
官方是有案例的,想更多学习可以给与参考,但是估计要多看几遍,有node基础的就比较好理解一些。
下面是官网地址:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#method-cloud
下面开始说我自己的方法;
1.首先构建云函数,需要两个云函数,一个用来解密,session_key,一个用来解密加密手机号码;
//云函数:getSession;
// 云函数入口文件
const cloud = require('wx-server-sdk')
//npm install request-promise 通过终端下载npm install wx-server-sdk ,
const rp = require('request-promise');
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const _JSCODE = event.code
const AccessToken_options = {
method: 'GET',
url: 'https://api.weixin.qq.com/sns/jscode2session',
qs: {
appid: '', //你的小程序appid;
secret: '', //你的秘钥
grant_type: 'authorization_code',
js_code: _JSCODE
},
json: true
};
const resultValue = await rp(AccessToken_options);
return { resultValue }
}
下载好需要的两个包,就可以对云函数初始化,执行npm init
有个起名字的环节,用过node的都知道,默认index.js,有个选择
package name: (gettoken) index.js
version: (1.0.0)
description:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\projects\zy_face_id_wxs\server\getToken\package.json:
{
"name": "index.js",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"request-promise": "^4.2.4",
"wx-server-sdk": "^0.8.1"
},
"devDependencies": {},
"description": ""
}
Is this OK? (yes) yes
这是初始化,终端的代码;
右键点击上传并部署到云端;
下面是客户端的代码;
getPhoneNumber(e) {
if (!e.detail.errMsg || e.detail.errMsg != "getPhoneNumber:ok") {
wx.showModal({
content: '不能获取手机号码',
showCancel: false
})
return;
}
wx.showLoading({
title: '获取手机号中...',
})
console.log(e)
wx.login({
success(res) {
if (res.code) {
console.log(res.code)
console.log(e.detail.iv)
console.log(e.detail.encryptedData)
wx.cloud.callFunction({
name: 'getSession', //调用云函数获取session_key;
data: {
code: res.code,
},
success: res => {
wx.hideLoading()
// console.log(res.result.resultValue)
var data = res.result.resultValue
console.log(data)
console.log(data.session_key) //获取到了session_key的值;
},
fail: error => {
console.log(error)
}
})
}
}
})
},
2.构建第二个云函数 GetWX;
// 云函数入口文件
const cloud = require('wx-server-sdk')
// const requestpromise = require('request-promise');
var WXBizDataCrypt = require('./RdWXBizDataCrypt') // 用于手机号解密
cloud.init()
exports.main = async (event, context) => {
const session_key = event.session_key
//appid写入你自己的appid,session_key 用第一个云函数的返回值;
const pc = new WXBizDataCrypt(appid, session_key ) // -解密第一步
const data = pc.decryptData(event.encryptedData, event.iv) // 解密第二步
return {
data
}
}
这个同样执行上面的步骤,npm install wx-server-sdk 和初始化npm init;
重点来了,解密所需要的js文件。
`
这两个文件已经上传到我的网盘里面,需要的请下载;
- https://pan.baidu.com/s/1VrS1gX_Bw3dKaZkQnNzy2A
- 提取码:cxnh;
- 格式和图片的保持一致,并上传到云端。
3.开始前端调用了;
代码如下;
getPhoneNumber(e) {
if (!e.detail.errMsg || e.detail.errMsg != "getPhoneNumber:ok") {
wx.showModal({
content: '不能获取手机号码',
showCancel: false
})
return;
}
wx.showLoading({
title: '获取手机号中...',
})
console.log(e)
wx.login({
success(res) {
if (res.code) {
console.log(res.code)
console.log(e.detail.iv)
console.log(e.detail.encryptedData)
wx.cloud.callFunction({
name: 'getSession', //调用云函数获取session_key;
data: {
code: res.code,
},
success: res => {
wx.hideLoading()
var data = res.result.resultValue
console.log(data)
console.log(data.session_key) //获取到了session_key的值;
const session_key=data.session_key
wx.cloud.callFunction({
name:'getWX', //解析秘文,获得手机号码;
data:{
session_key: session_key,
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
},
success:res=>{
console.log(res)
},
fail:err=>{
console.log(err)
}
})
},
fail: error => {
console.log(error)
}
})
}
}
})
},
4.输出的结果:
遇到问题了在私信问我,一一回答。
牛逼
你好,感谢提供内容。有个疑问,最终解密手机号码后,图中圈红的地方展示的数据是一个[object Object],要如何解析呢?
您好,session_key已经获取成功,在GetWX这个云函数时,RdWXBizDataCrypt.js文件提示这个报错,请问是什么原因呢?
新版 通过cloudID可以直接解密。
onShow: function () {
wx.clearStorageSync('session_key')
wx.login({ //换取code值,
success(res) {
if (res.code) {
wx.cloud.callFunction({
name: 'GetSessions', //调用云函数获取session_key;
data: {
code: res.code,
},
success: res => {
var data = res.result.resultValue
console.log(data)
wx.setStorage({
key: "session_key",
data: {
session_key: data.session_key,
open_id: data.openid
}
})
}
})
}
}
})
},
先获取code,从而换取session_key,避免出现官方提示的错误。
普通个人开发者可以用这个么?
楼主您好!复制您的方法,为啥出现这个提示,请指教!
Error: errCode: -404011 cloud function execution error | errMsg: cloud.callFunction:fail requestID c970bc35-dcd8-11e9-9e4e-525400681fe1, cloud function service error code -504002, error message Cannot find module 'request-promise'; at cloud.callFunction api;
{"errorCode":1,"errorMessage":"user code exception caught","stackTrace":"First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object."}
会出现这个错误是啥回事?
index.js
// 云函数入口文件
const cloud = require(
'wx-server-sdk'
)
var
WXBizDataCrypt = require(
'./WXBizDataCrypt'
)
const requestSync = require(
'./requestSync'
)
cloud.init({
env:
'xxxx'
,
traceUser:
true
})
// 云函数入口函数
exports.main = async (event, context) => {
var
appId = cloud.getWXContext().APPID
var
code = event.code
var
encryptedData = event.encryptedData
var
iv = event.iv
const secret =
'xxxxxxxxxxxxxxx'
const url = {
url:
'https://api.weixin.qq.com/sns/jscode2session?appid='
+ appId +
'&secret='
+ secret +
'&js_code='
+ code +
'&grant_type=authorization_code'
}
const req = await requestSync(url);
const session = JSON.parse(req);
const sessionKey = session.session_key;
var
pc =
new
WXBizDataCrypt(appId, sessionKey)
var
data = pc.decryptData(encryptedData, iv)
console.log(
"data = "
, data)
return
data
}
WXBizDataCrypt.js
var
crypto = require(
'crypto'
)
function
WXBizDataCrypt(appId, sessionKey) {
this
.appId = appId
this
.sessionKey = sessionKey
}
WXBizDataCrypt.prototype.decryptData =
function
(encryptedData, iv) {
// base64 decode
console.log(
"errr1"
)
var
sessionKey =
new
Buffer(
this
.sessionKey,
'base64'
)
console.log(
"errr2"
)
encryptedData =
new
Buffer(encryptedData,
'base64'
)
console.log(
"errr3"
)
var
iv =
new
Buffer(iv,
'base64'
)
try
{
// 解密
var
decipher = crypto.createDecipheriv(
'aes-128-cbc'
, sessionKey, iv)
// 设置自动 padding 为 true,删除填充补位
decipher.setAutoPadding(
true
)
var
decoded = decipher.update(encryptedData,
'binary'
,
'utf8'
)
decoded += decipher.final(
'utf8'
)
console.log(
"errr4"
)
decoded = JSON.parse(decoded)
}
catch
(err) {
throw
new
Error(
'Illegal Buffer 1'
)
}
if
(decoded.watermark.appid !==
this
.appId) {
throw
new
Error(
'Illegal Buffer 2'
)
}
return
decoded
}
module.exports = WXBizDataCrypt
之前都一直正常运行的。
打印到一个错误,
{
"errcode"
:40125,
"errmsg"
:
"invalid appsecret, view more at http:\/\/t.cn\/RAEkdVq, hints: [ req_id: ]"
}
invalid appsecret
是什么?获取个手机号需要这么多js吗