so_easy
so_easy
  • 发布:2019-01-09 22:47
  • 更新:2020-12-20 18:30
  • 阅读:22356

uni-app 编写小程序怎么获取微信手机号

分类:uni-app

<button>按钮已经绑定getPhoneNumber事件
<button type="primary" open-type="getPhoneNumber" @getPhoneNumber="getPhoneNumber">微信登录</button>

但是在小程序开发工具运行,点击【微信登录】按钮,页弹出获取手机号的弹出框,但是点击弹出框的按钮,没有任何反应。

2019-01-09 22:47 负责人:无 分享
已邀请:
skysowe

skysowe

荟萃了一下社区里的大家的代码,发现是可以取到微信小程序绑定的手机号的,完整代码如下:

这里面有几个知识点,做过微信公众号开发的同学肯定明白:

  1. 如何从微信后台获取jscode
  2. 通过APPID + SECRET + jscode 三个参数访问 https://api.weixin.qq.com/sns/jscode2session 换取session_key;
  3. getPhoneNumber函数,如果用户同意授权,得到encryptedData和iv;
  4. 通过微信官方的WXBizDataCrypt,用手中的APPID和session_key,解密encryptedData,得到手机号,拿到UserInfo和OpenId的方法类似

总结一下:首先得到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>  
  • 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

Neil_HL

Neil_HL

试试小程序的真机预览

  • so_easy (作者)

    真机预览也没有反应


    2019-01-10 11:27

  • so_easy (作者)

    我把@getPhoneNumber 换成 bindgetPhoneNumber 运行,就会提示没有方法来处理getPhoneNumber事件


    2019-01-10 11:29

  • so_easy (作者)

    @getPhoneNumber,下面写getPhoneNumber function(e){} 返回的参数e里面没有encryptedData、iv等有关的参数


    2019-01-10 11:32

大笨蛋

大笨蛋 - 打杂的

解决了吗

7***@qq.com

7***@qq.com - 愿您的代码可以改变世界

@getphonenumber="getPhoneNumber" ???

x***@163.com

x***@163.com

我的支付宝上写原生的方法调不起来

4***@qq.com

4***@qq.com

感觉屁用没有 完全看不到手机号

l***@outlook.com

l***@outlook.com

同问,这个什么原因

小米

小米

遇到了同样的问题,有人解决了吗

3***@qq.com

3***@qq.com

WXBizDataCrypt在哪里找到

1***@qq.com

1***@qq.com

我下载微信官方的的WXBizDataCrypt文件到项目中,WXBizDataCrypt文件编译到小程序有600多k,你们有遇到这种情况吗

1***@qq.com

1***@qq.com - 攻城狮

复制您的代码没有弹窗出现,
console.log(JSON.stringify(e.detail.encryptedData));
console.log(JSON.stringify(e.detail.iv)); 取不到值

  • 4***@qq.com

    你这个出错提示怎么解决的?


    2020-12-20 21:13

c***@qq.com

c***@qq.com - vuer

现在又遇到这种情况了,问一下各位怎么解决的

cydida

cydida

微信手机号快捷登录 第一次必定失败,第二次就好了,不管使用真机预览,还是发行模式。

cydida

cydida

微信手机号快捷登录 第一次必定失败,第二次就好了,不管使用真机预览,还是发行模式。

4***@qq.com

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> }

发现获取微信相关信息原来这么不方便,有没有同学帮帮我?

该问题目前已经被锁定, 无法添加新回复