HBuilderX(uniapp)实现微信小程序获取用户头像、昵称、授权登录、获取用户手机号

前言:微信文档写的零零散散的,网上搜的教程,23年的教程还在教22年改版之前的东西,导致踩坑无数,所以自己写一下文档记录一下,帮助后来者,记录于2024.11.14

一.获取用户头像和昵称

首先阅读微信小程序官方文档,wx.getUserInfo接口开放接口 / 用户信息 / wx.getUserInfo (qq.com)

发现自2022年之后,开发的版本逐渐对用户信息接口更改,wx.getUserInfo接口已经基本弃用,之前老版本还能够使用,但是新版小程序调用此接口只能获取到一堆默认信息如下









​​​​​​
​   小程序登录、用户信息相关接口调整说明 | 微信开放社区 (qq.com)

所以要实现获取用户头像,不能像之前一样一键获取了,有的文档说会调起一个授权弹窗,然后用户手动授权之后就可以获取,亲测这个方法已经过时,即下图这个方法并不会弹出个人信息确认弹窗

目前唯一可行的方法就是:头像昵称填写能力

开放能力 / 用户信息 / 获取头像昵称 (qq.com)

需要将 button 组件 open-type 的值设置为 chooseAvatar,当用户选择需要使用的头像之后,可以通过 bindchooseavatar 事件回调获取到头像信息的临时路径。

需要将 input 组件 type 的值设置为 nickname,当用户在此input进行输入时,键盘上方会展示微信昵称。

其中有两个需要注意的点:

1.选择的微信头像是暂存到本地的路径,随时可能会失效,或者出现307重定向等一系列bug,所以要把头像上传的自己本地的服务器,或者本地的接口保存,就是把onChooseAvatar方法修改成如下

onChooseAvatar: function(e) {
				const {
					avatarUrl
				} = e.detail
				let _this = this
				wx.uploadFile({
					url: '',   // 你自己本地上传图片的 完整 路径
					filePath: avatarUrl,
					name: 'file', // 文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容
					success(res) {
						console.log("data===>",res.data)
						_this.setData({
							avatarUrl:'' // 你自己的完整图片路径
						})
					}
				})
			},

2.微信昵称选择的时候,输入框有值,并且绑定了v-model,并不会被监听到,即使修改了,值也还是空的,必须要用户手动再修改才会被v-model发现修改,这是一个bug吧,所以要手动用watch监听一下输入框绑定的值

获取头像昵称示例代码如下:

<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
  <image class="avatar" src="{{avatarUrl}}"></image>
</button> 
<input type="nickname" class="weui-input" placeholder="请输入昵称"/>

const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'

export default{
    data(){
        avatarUrl: defaultAvatarUrl, // 可以自行修改
    },
    methods:{
        
    }
}
 
  onChooseAvatar(e) {    // 将这个方法修改为上面那个,注意变量名更改
    const { avatarUrl } = e.detail 
    this.setData({
      avatarUrl,
    })
  }
})

二.微信授权登录

主要用到的接口就是wx.login接口,其功能如下:

调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台账号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台账号)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。

很抽象,通俗来讲,就是调用wx.login接口,微信会给你返回一个code,通过这个code传给后端,后端会通过系列操作(这个系列操作后面会讲)返回给你一个openid,unionid和session_key,作用我都会一一介绍。然后上文说的解密通讯是交给后端完成的。

openid作用是用户在本小程序的唯一作用标识。

unionid是多个小程序之间,同一用户,不用重新授权即可直接登录的标识,此unionid需要注册微信开放平台认证才可获得,如果只是开发一个小程序则不需要这个id。

session_key:五分钟一次刷新,用来判断登录是否过期。

首先我们来阅读官方文档开放接口 / 登录 / wx.login (qq.com)

下图是从别的博客借鉴来的,三列,第一列是前端要做的,第二列是后端要做的

首先,在登录界面的onLoad函数中调用wx.login

onLoad: function(options) {
			let that = this;
			wx.login({
				success: res => {
					that.code = res.code
				}
			})
		},

把这个code保存下来。然后通过自己的wxLogin把这个code传给后端,后端阅读这个文档

小程序登录 / 小程序登录 (qq.com)

调用微信的服务

GET https://api.weixin.qq.com/sns/jscode2session

后端直接配置下面四个参数然后调用

appid和secret在微信小程序的平台内可以查看到,js_code就是前端传入的code,下一个参数直接填写authorization_code即可、然后微信服务器会返回openid等参数,然后把这个openid返回给前端,同时在这个login接口里面注册用户保存到数据库,把userId和openid一起返回给前端,到此登录流程就结束了。

三.获取用户手机号

阅读官方文档开放能力 / 用户信息 / 手机号快速验证组件 (qq.com)

<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">微信授权登录</button>

注意,现在手机号快速验证需要收费了,如果你是个人appid,则需要完成微信小程序认证,300一年,如果不想认证还想用这个功能,就要用测试号,把appid和secret都换成测试号的。

而且现在这个获取用户手机号,不用wx.login也可以登录

使用方法

步骤1:需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,通过 bindgetphonenumber 事件获取回调信息;

步骤2:将 bindgetphonenumber 事件回调中的动态令牌code传到开发者后台,并在开发者后台调用微信后台提供的 phonenumber.getPhoneNumber 接口,消费code来换取用户手机号。每个code有效期为5分钟,且只能消费一次。

注:getPhoneNumber 返回的 code 与 wx.login 返回的 code 作用是不一样的,不能混用。这句话很重要!!在和授权登录一起写的时候很容易弄混。

我是直接全都在前端调用了,效果如下

!!!今天上线体验版的时候发现,https://api.weixin.qq.com这个域名不能配置为合法域名,微信直接把这个禁用了,即这一段代码全都必须只能放在后端运行,即后端写一个接口,接受code参数,然后把下面代码中的e.detail.code这个参数传给后端,下面的一系列post微信服务的接口都由后端来完成,直接返回电话号码即可、

文档:获取手机号 | 微信开放文档

后端操作:
先调用https://api.weixin.qq.com/cgi-bin/stable_token,post方法,传参grant_type: 'client_credential', appid: config.appid, secret: config.secret


获取到token,这个token是获取手机号的token,不是登录的token


然后调用url: `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=` + token,post方法,传参code,返回的数据就是包含手机号的数据
 

getPhoneNumber(e) {
				console.log("e=>", e) // 这里会返回encryptedData和iv,用来加密和解密
				if (e.detail.errMsg === 'getPhoneNumber:ok') {
					// this.encryptedData = e.detail.encryptedData
					// this.iv = e.detail.iv
					const code = e.detail.code;
					let promise = new Promise((resolve, reject)=> {
					  var params = {
					  	url: '/login',
					  	data: {
					  		principal: this.code,
					  	},
					  	callBack: res => {
					  		http.loginSuccess(res)  // 这是我自己外部文件保存登录token等信息
					  	}
					  }
					  http.request(params)
					  resolve();
					});
					promise.then((res)=>{
						uni.request({
							url: `https://api.weixin.qq.com/cgi-bin/stable_token`,
							method: "POST",
							data: {
								grant_type: 'client_credential',
								appid: config.appid,
								secret: config.secret
							},
							success: res => {
                                // 此token和code不是login的token和code,这一步可以放到后端写
								this.getPhone(res.data.access_token, code);
							},
							fail: err => {
								console.error("调用失败=>", err);
							}
						});
					})
				} else {
					console.error('用户未授权手机号');
					uni.showToast({
						title: '用户未授权手机号',
						icon: 'none'
					});
				}
			},
            getPhone(token, code) {
				// 获取手机号
				uni.request({
					url: `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=` + token,
					method: "POST",
					data: {
						code: code
					},
					success: res => {
						console.log("获取到的用户手机号全部信息:", res);
						// 获取到手机号
						this.phoneNumber = res.data.phone_info.purePhoneNumber;
						console.log("流程结束!!")
					},
					fail: err => {
						console.error("获取手机号失败", err);
						uni.showToast({
							title: '获取手机号失败',
							icon: 'none'
						});
					}
				});
			},

手动删减的,有的地方花括号可能会有报错,请见谅,但大体流程就是上面那样,最后res.data.phone_info.purePhoneNumber就是最终的用户手机号。

获取手机号和微信授权登录可以写到同一个按钮里面,具体逻辑可以自己操作

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值