<button>按钮已经绑定getPhoneNumber事件
<button type="primary" open-type="getPhoneNumber" @getPhoneNumber="getPhoneNumber">微信登录</button>
但是在小程序开发工具运行,点击【微信登录】按钮,页弹出获取手机号的弹出框,但是点击弹出框的按钮,没有任何反应。
荟萃了一下社区里的大家的代码,发现是可以取到微信小程序绑定的手机号的,完整代码如下:
这里面有几个知识点,做过微信公众号开发的同学肯定明白:
总结一下:首先得到jscode => 然后得到session_key => 拿到encryptedData和iv => 解密出 UserInfo或者手机号
<template>
<view>
<!-- bindgetphonenumber -->
<!-- <button type="primary" open-type="getUserInfo" @getuserinfo="getUserInfo" withCredentials="true">微信登录</button> -->
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">获取电话号码</button>
</view>
</template>
<script>
//微信提供的解密函数,请修改为你自己的路径
var WXBizDataCrypt = require('@/pages/login/WXBizDataCrypt.js');
export default {
data() {
return {
login_code : '',
};
},
onLoad: function() {
var that = this;
uni.login({
success: function(res) {
// 获取code
console.log(JSON.stringify(res));
//{"errMsg":"login:ok","code":"071JIp1t1pv马赛克t1Ran1t1JIp1l"}
that.login_code = res.code;
}
});
},
methods: {
getPhoneNumber: function(e) {
console.log(e);
if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
console.log('用户拒绝提供手机号');
} else {
console.log('用户同意提供手机号');
console.log(JSON.stringify(e.detail.encryptedData));
console.log(JSON.stringify(e.detail.iv));
var encryptedData = e.detail.encryptedData;
var iv = e.detail.iv;
////////////////////////////////////////////////////////////////////////////////
//定义在根目录下的main.js里
//Vue.prototype.APPID = 'wxb1a马赛克2bfc90a';
//Vue.prototype.SECRET = 'b3ae36758马赛克dbe146d9acd81d';
//Vue.prototype.WX_AUTH_URL = 'https://api.weixin.qq.com/sns/jscode2session';
var JSCODE = this.login_code;
var APPID = this.APPID;
var SECRET = this.SECRET;
var wx_author_url = this.WX_AUTH_URL + '?appid=' + APPID + '&secret=' + SECRET + '&js_code=' + JSCODE + '&grant_type=authorization_code';
uni.request({
url : wx_author_url,
success(re){
console.log( 'session_key:' + re.data.session_key );
var appId = APPID;
var sessionKey = re.data.session_key;
var pc = new WXBizDataCrypt(appId, sessionKey);
var data = pc.decryptData(encryptedData, iv);
console.log('------------------->');
console.log('解密后 data: ', data);
// console.log('解密后 data: ', JSON.stringify(data));
/*
{
"phoneNumber": "139马赛克9490",
"purePhoneNumber": "139马赛克9490",
"countryCode": "86",
"watermark": {
"timestamp": 1560577589,
"appid": "wxb1a马赛克12bfc90a"
}
}
*/
console.log('------------------->');
}
});
////////////////////////////////////////////////////////////////////////////////
}
},
/*
getUserInfo: function(loginType, cb) {
var that = this
if (this.globalData.userInfo) {
typeof cb == "function" && cb(this.globalData.userInfo, true);
} else {
//1.调用登录接口
wx.login({
success: function() {
wx.getUserInfo({
success: function(res) {
that.globalData.userInfo = res.userInfo;
typeof cb == "function" && cb(that.globalData.userInfo, true);
},
fail: function() {
//2.第一次登陆不强制授权,直接返回
if (loginType == 0) {
typeof cb == "function" && cb(that.globalData.userInfo, false);
} else {
//3.授权友好提示
wx.showModal({
title: '提示',
content: "您还未授权登陆,部分功能将不能使用,是否重新授权?",
showCancel: true,
cancelText: "否",
confirmText: "是",
success: function(res) {
//4.确认授权调用wx.openSetting
if (res.confirm) {
if (wx.openSetting) { //当前微信的版本 ,是否支持openSetting
wx.openSetting({
success: (res) => {
if (res.authSetting["scope.userInfo"]) { //如果用户重新同意了授权登录
wx.getUserInfo({
success: function(res) {
that.globalData.userInfo = res.userInfo;
typeof cb == "function" && cb(that.globalData.userInfo, true);
}
})
} else { //用户还是拒绝
typeof cb == "function" && cb(that.globalData.userInfo, false);
}
},
fail: function() { //调用失败,授权登录不成功
typeof cb == "function" && cb(that.globalData.userInfo, false);
}
})
} else {
typeof cb == "function" && cb(that.globalData.userInfo, false);
}
} else {
typeof cb == "function" && cb(that.globalData.userInfo, false);
}
},
})
}
}
})
}
})
}
}
*/
}
}
</script>
<style>
</style>
1***@qq.com - 攻城狮
复制您的代码没有弹窗出现,
console.log(JSON.stringify(e.detail.encryptedData));
console.log(JSON.stringify(e.detail.iv)); 取不到值
4***@qq.com - 暖水袋
如果后端采用uniCloud来完成的话,该如何做?我试着写了一个云函数,但执行后返回的不知道是啥,如下:
'use strict';
exports.main = async (event, context) => {
//event为客户端上传的参数
//console.log('event : ', event)
const res=uniCloud.httpclient.request(
'https://api.weixin.qq.com/sns/jscode2session', {
method: 'GET',
data: {
appid: "xxxxxxxxxx", //你的小程序的APPID
secret: "xxxxxxxxxx", //你的小程序的secret,
code: "xxxxxxxxxx" //wx.login 登录成功后的code
}
})
console.log(res)
};
执行上传并运行,返回的结果是:
Promise { <pending> }
发现获取微信相关信息原来这么不方便,有没有同学帮帮我?
skysowe
以上实现,技术上是没问题的,确实获取到了手机号码和OpenId,但是只适合用于调试模式,,因为微信小程序有域名白名单机制,而微信自身的api.weixin.qq.com不在合法域名内,详见微信官方的文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/network.html ;小程序作为客户端,确实存放AppId和SECRET是不合适的,有安全隐患,微信官方的建议是,这部分代码应该放在服务器端,首先在【客户端】得到jscode =>发送到【服务器端】 ,【服务器端】得到session_key发送给【客户端】 =>【客户端】 拿到encryptedData和iv => 解密出 UserInfo或者手机号
2019-06-15 20:15
seho20001123
回复 skysowe: 能否WXBizDataCrypt把这个js贴一下,我在微信官方没找到,谢谢啦,万分感谢
2019-07-01 17:53
seho20001123
回复 skysowe: 哎呀,我看到了
2019-07-01 17:54
seho20001123
请问这个app_id,是开发平台的id还是小程序的id;我这边请求错误了;参数都传的对的;{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: bIadn_4ce-RbEJXa ]"}
2019-07-01 18:04
skysowe
回复 seho20001123: 这里的app_id当然是微信小程序后台的app_id
2019-07-02 09:36
skysowe
上面的代码仅供测试使用,开发版没有任何问题,弄懂了原理之后,在实际项目中,我是把访问https://api.weixin.qq.com/sns/jscode2session 通过jscode获取session_key的操作放在了后台,然后把session_key返回到手机端,再加上app_id,用WXBizDataCrypt获取了手机号或用户的完整信息
2019-07-02 10:25
1***@qq.com
回复 skysowe: 复制您的代码没有弹窗出现,点击获取手机号码
console.log(JSON.stringify(e.detail.encryptedData));
console.log(JSON.stringify(e.detail.iv)); 取不到值
2020-01-06 15:50
2***@qq.com
回复 seho20001123: 请问你在哪下载的WXBizDataCrypt.js呢?
2020-08-14 14:20
skysowe
回复 2***@qq.com: 社区的附件很不明显,就在代码下面第一行
2020-08-15 11:41