微信小程序手机号如何授权——过程与细节(sessionKey过期,wx.checkSession())

本文详细介绍了微信小程序获取用户手机号的流程,包括使用button组件触发授权,wx.checkSession检测sessionKey是否过期,以及解密手机号的步骤。特别强调了sessionKey过期可能导致的解密失败问题,并分析了可能的原因。此外,还提醒开发者注意wx.login的潜在影响,以及在实际项目中可能出现的解密失败场景。同时,提供了相关按钮样式的参考代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小程序手机号如何授权——过程与细节(sessionKey过期,wx.checkSession())

一切来源于官方文档。
官方文档中,button组件中就有提供专门用于获取手机号的写法;——小程序开放文档
进入具体说明可以看到:官方代码示例
在这里插入图片描述

<button class="login_btn" plain="true" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button>
getPhoneNumber:function(e){
	var that = this;
	if(wx.getStorageSync("session_key")){//先判断缓存中是否有session_key,
		wx.checkSession({//检测session_key是否过期
			success: function() {
				console.log("未过期")
				if(e.detail.errMsg=='getPhoneNumber:ok'){
					console.log(e)
					that.$http('xxxx解密手机号接口',{//将手机号授权返回的参数,传给后端,进行手机号解密
						sessionKey:wx.getStorageSync('session_key'),
						encryptedData:e.detail.encryptedData,
						iv:e.detail.iv,
						}).then(res=>{
						if(res.code==20000){
							console.log(res.data)//成功拿到用户手机号
							
						}else{
						  
						}
					})
				}else{
				  
				}
				
			},
			fail: function () {//session_key过期,则需要微信登录接口wx.login(),来重新获取session_key
				console.log("过期")
				wx.login({
					success(res) {
					console.log('wxlogin',res);
					if (res.code) {
					  // 服务器端接口--获取sessionKey
					  that.$http('xxx获取session_key接口',{//,那code换取session_key,和并存入缓存
						code:res.code,
					  }).then(res=>{
						if(res.code==20000){
						  wx.setStorageSync('session_key', res.data.session_key);
						  if(e.detail.errMsg=='getPhoneNumber:ok'){
								console.log(e)
								
								that.$http('xxxx解密手机号接口',{//将手机号授权返回的参数,传给后端,进行手机号解密
									sessionKey:wx.getStorageSync('session_key'),
									encryptedData:e.detail.encryptedData,
									iv:e.detail.iv,
									}).then(res=>{
									if(res.code==20000){
										console.log(res.data)//成功拿到手机号
										
									}else{
									  
									}
								})
						  }else{
						    
						  }
						}
					  })
					} else {
					  console.log('失败!' + res.errMsg)
					}
				  },
				  fail(res){
					console.log('error',res);
				  }
				})
			 }
		})
	}else{//如果缓存中没有session_key,直接按步骤,登录,拿session_key,进而获取手机号
		wx.login({
			success(res) {
			console.log('wxlogin',res);
			if (res.code) {
			  // 服务器端接口--获取sessionKey
			  that.$http('xxx获取session_key接口',{
				code:res.code,
			  }).then(res=>{
				if(res.code==20000){
				  wx.setStorageSync('session_key', res.data.session_key);
				  if(e.detail.errMsg=='getPhoneNumber:ok'){
						console.log(e)
						
						that.$http('xxxx解密手机号接口',{
							sessionKey:wx.getStorageSync('session_key'),
							encryptedData:e.detail.encryptedData,
							iv:e.detail.iv,
							}).then(res=>{
							if(res.code==20000){
								console.log(res.data)//成功拿到手机号
								
							}else{
							  
							}
						})
				  }else{
				    
				  }
				}
			  })
			} else {
			  console.log('失败!' + res.errMsg)
			}
		  },
		  fail(res){
			console.log('error',res);
		  }
		})
	}
	},

总结:正常按照官方文档操作就没什么大问题,只不过尤其要注意一下,sessionKey是否过期,如果过期就会出现解密失败,这也是为什么有的同志在实际项目中遇到,明明之前可以的,怎么有的时候解密失败啊。

重点来了:关于wx.checkSession,微信社区有反馈bug,说调用wx.checkSession一直走success,然后实际调用手机号解密却又失败。。。。。
(这里做出我自己的分析:之所以wx.checkSession一直走success,很大可能是因为小程序默认的在app.js文件中的wx.login()方法没有删除,导致你在手机号授权页之前就更新了登录态,所以一直成功;也可能是因为特殊业务的原因在别的页面也有wx.login()的方法存在。接下来说一说为啥sessionKey没过期,但是手机号解密却失败呢?原因可能有几种情况:1,登录态未过期,其实真的不代表你的sessionKey就不过期,尤其是我这种不按官方来,非要把sessionKey存在我客户端的人来说;2,借着1来说,也可能就是你的sessionKey没有更新,这种没更新可能就是你别的地方调用wx.login()中紧接着调用的接口后端处理时是会更新sessionKey的,但是你没有更新你本地的sessionKey,可以检查下,因为你不可能就单单调个wx.login(),里面肯定有接口请求的,看一下;3,就是看下图:
在这里插入图片描述
有的同志可能想着我在回调里紧跟着调用wx.login()拿到最新的sessionKey不就不怕过期了吗?哎!完犊子,此时sessionKey是最新的了,但是手机号回调加密的内容是先触发的啊,早于你新生成的sessionKey啊,换句话说,加密的是老的那个当时还未过期的sessionKey,然后你这会再拿最新的sessionKey去解密,势必解密失败的。当然如果是像我上头代码里的,首次调用时,在回调里拿sessionkey就是没问题的)

补充:关于button样式的问题,因为授权必须通过button来触发,但是直接复制过来的button样式又没办法用,需要自己去改;

.login_btn{
	width: 100rpx;
	height: 44rpx;
	padding: 0;
	background-color: transparent;
	border-radius: 22rpx;
	border-color: #ffffff;
	line-height: 40rpx;
	font-size: 26rpx;
	outline: none;
	color: #ffffff;
	margin: 0;
	margin-bottom: 12rpx;
}

实际样式结合业务调整即可
在这里插入图片描述
这个属性也可以作为参考。

### 微信小程序手机号授权登录流程 微信小程序中实现手机号授权登录的流程主要分为以下几个部分:小程序端用户授权、服务端处理以及最终获取手机号。以下是详细的实现步骤和代码示例。 #### 1. 小程序端用户授权小程序端,需要通过 `<button>` 组件来触发用户的手机号授权操作。此组件必须设置 `open-type="getPhoneNumber"` 属性,并绑定一个事件处理函数以接收回调数据[^3]。 ```html <button bindgetphonenumber="getPhoneNumber" open-type="getPhoneNumber" class='button-hover'>确认授权</button> ``` 当用户点击按钮时,会弹出授权框,提示用户是否同意提供手机号。如果用户同意,则会触发 `bindgetphonenumber` 事件,并将加密数据传递给小程序端[^4]。 #### 2. 小程序端处理回调数据 在小程序端,接收到授权后的回调数据后,需要将其发送到服务端进行解密处理。以下是一个简单的事件处理函数示例: ```javascript Page({ getPhoneNumber(e) { if (e.detail.errMsg === "getPhoneNumber:ok") { // 获取加密数据 const encryptedData = e.detail.encryptedData; const iv = e.detail.iv; // 将数据发送到服务端 wx.request({ url: 'https://your-server-url/decryptPhoneNumber', // 替换为你的服务端地址 method: 'POST', data: { encryptedData: encryptedData, iv: iv, sessionKey: wx.getStorageSync('sessionKey') // 假设已存储 sessionKey }, success(res) { console.log("解密成功:", res.data.phoneNumber); }, fail(err) { console.error("解密失败:", err); } }); } else { console.error("用户拒绝授权"); } } }); ``` #### 3. 服务端解密数据 服务端接收到小程序端发送的加密数据后,需要使用微信提供的解密算法进行解密,从而获取用户的手机号[^5]。以下是一个 Python 示例代码: ```python from Crypto.Cipher import AES import base64 import json class WXBizDataCrypt: def __init__(self, app_id, session_key): self.app_id = app_id self.session_key = session_key def decrypt(self, encrypted_data, iv): # base64 decode session_key = base64.b64decode(self.session_key) encrypted_data = base64.b64decode(encrypted_data) iv = base64.b64decode(iv) cipher = AES.new(session_key, AES.MODE_CBC, iv) decrypted = json.loads(self._unpad(cipher.decrypt(encrypted_data))) if decrypted['watermark']['appid'] != self.app_id: raise Exception('Invalid Buffer') return decrypted def _unpad(self, s): return s[:-ord(s[len(s)-1:])] ``` 使用上述类解密数据的示例: ```python crypt_tool = WXBizDataCrypt(app_id="your_app_id", session_key="your_session_key") decrypted_data = crypt_tool.decrypt(encrypted_data="your_encrypted_data", iv="your_iv") print(decrypted_data["phoneNumber"]) ``` #### 4. 返回手机号小程序端 解密完成后,服务端可以将手机号返回给小程序端,供后续逻辑使用。例如,更新用户信息或完成登录操作。 --- ### 注意事项 - 确保小程序已配置 `wx.login` 获取 `code` 并通过 `code2Session` 接口获取 `session_key`。 - 在服务端解密时,需验证 `watermark.appid` 是否小程序的 `appid` 一致[^5]。 - 用户主动点击按钮是获取手机号的必要条件,无法通过其他方式直接获取[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值