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

小程序手机号如何授权——过程与细节(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;
}

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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,uniapp微信小程序可以通过以下步骤实现手机号一键登录: 1.在uniapp项目安装并引入wx-server-sdk模块,该模块可以用于调用云函数。 2.在云函数使用wx-server-sdk模块的getPhoneNumber方法获取用户手机号码。 3.在小程序使用wx.login方法获取用户的code。 4.将获取到的code和encryptedData、iv等信息传递给云函数。 5.在云函数使用code、encryptedData、iv等信息调用微信提供的解密算法,获取用户的手机号码。 6.将获取到的手机号码返回给小程序端,实现一键登录功能。 以下是示例代码: 1.云函数代码: ```javascript const cloud = require('wx-server-sdk') cloud.init() const wxContext = cloud.getWXContext() const appid = 'your appid' // 替换成自己的appid const appsecret = 'your appsecret' // 替换成自己的appsecret const wxServerSDK = require('wx-server-sdk') wxServerSDK.init({ env: wxContext.ENV, appid: appid, secret: appsecret }) exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const { code, encryptedData, iv } = event const session = await wxServerSDK.cloud.callFunction({ name: 'login', data: { code: code } }) const sessionKey = session.result.session_key const phone = await wxServerSDK.cloud.callFunction({ name: 'getPhoneNumber', data: { appid: appid, sessionKey: sessionKey, encryptedData: encryptedData, iv: iv } }) return phone.result } ``` 2.小程序端代码: ```javascript // 获取用户手机号码 getPhoneNumber: function (e) { wx.cloud.callFunction({ name: 'getPhoneNumber', data: { code: this.globalData.code, encryptedData: e.detail.encryptedData, iv: e.detail.iv }, success: res => { console.log(res.result) // TODO: 处理获取到的手机号码 }, fail: err => { console.error(err) } }) } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值