刚开始开发微信小程序的时候,想着实现手机验证码登入,后来查阅资料得知,发给用户的短信是要自己付费的。后来想想,微信获取用户的手机号一样可以保证手机号码的真实性,因为手机号既然可以绑定微信,那么肯定是被严格核验过的,然后就开始了获取手机号之旅,网上教程有很多,但不知什么原因,都是会少一些内容,有的只有前端代码,没有后端;有的后端代码是PHP,不是我们想要的 Java 或者Javascript。我抱着开源的思想,给大家分享我获取手机号的办法,希望能帮到大家。
首先我们可以去看一看官方文档,获取手机号大致分为以下四步:
- 第1步:使用wx.login接口获取code(临时数据)
- 第2步:使用第一步的code,获取session_key和openid(确认用户唯一的数据)
- 第3步:使用getPhoneNumber接口,获取iv和encryptedData(获取加密的数据)
- 第4步:解密返回数据,获取手机号码(解密后的数据)
下面详细讲解:
第一步:使用wx.login接口获取code(临时数据)
官方文档是这么写的:
获取微信用户绑定的手机号,需先调用wx.login接口。
因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 button 组件的点击来触发。
注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。
我们可以提炼出下面几条关键信息:
- 只能由非个人的小程序才能获取用户手机号。
- 获取手机号必须由button按钮组件触发,而不能写在onLoad()内自动获取。
- 需在必要的情况下使用。
第一步获取code的代码和运行截图和第二步一起给,因为这两步必须写在一个方法内,不能单独两个方法,然后在onLoad()调用,因为小程序执行onLoad()内的方法,并不是按照代码先后顺序的(经验之谈)
第二步:使用第一步的code,获取session_key和openid(确认用户唯一的数据)
sessionkey和openid是用户的身份证明,一位用户在使用某一个小程序的时候,sessionkey是唯一的。当然一位用户在使用不同的小程序的时候,sessionkey是不一样的。
官网文档是这样写的:
我们需要拿来第一步获取到的code,来向服务器换取sessionkey和openid。
具体代码如下:
我们只需要在onLoad()这个生命周期函数内调用这个方法就可以了。
该方法首先调用wx.login()接口,获取到code,保存在页面变量code中,也就是第一步的操作代码。
接着调用wx.request()接口向服务器请求换取sessionkey和openid,再copy本代码的时候,你要替换掉appid和secret,这些可以在微信公众平台获取。
正常情况下,你就可以获取到sessionkey和openid了,当然如果你是个人认证的小程序,那恐怕就报错了。如果还有其他错误,欢迎在文章下方留言。
但是这只是在测试的时候可以获取,在实际运维的时候不能这样写,我们看微信官方文档的说明:
在微信开发者工具中,可以临时开启 开发环境不校验请求域名、TLS版本及HTTPS证书 选项,跳过服务器域名的校验。此时,在微信开发者工具中及手机开启调试模式时,不会进行服务器域名的校验。
在服务器域名配置成功后,建议开发者关闭此选项进行开发,并在各平台下进行测试,以确认服务器域名配置正确。
也就是说,https://api.weixin.qq.com/sns/jscode2session这个接口,我们不能直接去调用,这个时候,我们就要自己写一个jsp文件,放在Tomcat的webapp目录下,然后微信小程序通过这个jsp文件,来向微信服务器请求sessionkey和openid。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
这个jsp文件需要放在Tomcat安装目录的webapp,用来被微信小程序前台来请求数据。
同时,我们微信小程序前台代码也要稍加修改。改为向jsp文件获取,传上去一个参数code。
效果同下图所示:
第三步:使用getPhoneNumber接口,获取iv和encryptedData(获取加密的数据)
我们还是先来看官网文档怎么写的:
然后就是官网文档的demo:
1
2
3
4
5
6
7
8
9
10
11
我们可以从中看出:获取手机号必须由button按钮组件触发,而不能写在onLoad()内自动获取。
也就是说,这一步不需要我们进行什么操作,只要在WXML定义一个按钮,加上open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"属性,然后在JS文件中写一个getPhoneNumber方法,该方法有一个参数e,我们可以从这个e中获取iv和encryptedData,这个encryptedData就是加密的数据,其中包括我们需要的电话号码。
那么,接下来就需要我们解密了。
第四步:解密返回数据,获取手机号码(解密后的数据)
我们还是先来看官方文档:
微信会对这些开放数据做签名和加密处理。开发者后台拿到开放数据后可以对数据进行校验签名和解密,来保证数据不被篡改。
接口如果涉及敏感数据(如wx.getUserInfo当中的 openId 和 unionId),接口的明文内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接口返回的加密数据(encryptedData) 进行对称解密。 解密算法如下:
对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
对称解密的目标密文为 base64_Decode(encryptedData)。
对称解密秘钥 aeskey = base64_Decode(session_key), aeskey 是16字节。
对称解密算法初始向量 为base64_Decode(iv),其中iv由数据接口返回。
微信官方提供了多种编程语言的示例代码。每种语言类型的接口名字均一致。调用方式可以参照示例。
我们可以看出什么内容?关键的信息如下:
- 我们获取到了sessionkey和openid,要把sessionkey和openid用来解密第三步的加密数据。
- 我们需要用到某个高深的算法。
- 官方提供的解密算法没有Java和Javascript版。
我使用了Javascript版,改解密数据的模板结构如下,我会在下面把所有的代码提供给大家。
这个解密算法,会把第二步获取的sessionkey和openid,第三步获取的 iv和encryptedData,解密成真正的手机号码。
我们先来看获取手机号的页面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
我们先来看运行效果:
点击允许之后,开发工具的调试区域会打印如下信息:
这样就成功获取到了手机号码。
接下来是该Javascript解密算法的部分代码,因为代码太长了,放文章里面不太合适,我会单独上传到CSDN下载模块,拿来即用即可,大家也可以在下面评论区找我要文件,笔者每天都登CSDN,谢谢大家的理解和配合。
SHA1.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Crypto.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
CryptoMath.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
本文地址:http://lianchengexpo.xrbh.cn/quote/9835.html 迅博思语资讯 http://lianchengexpo.xrbh.cn/ , 查看更多