都知道之前的之前的获取用户信息的方法都获取不到真实的数据了 头像也是通用的灰色头像
提示:企业小程序才能获取到用户信息,个人的不行的哦
执行下面步骤之前,一定得先去吧微信小程序 微信认证 成功才能成功执行下面步骤 ,否则的话只能获取到微信临时头像
进入微信小程序首页 》 设置 》 基本信息填写完 》 通过之后点击基本设置里面有个微信认证
最后会有完整代码展示
首先
首先要去先执行 uni.login 方法,可以在onload 或 onshow 里面执行,避免后续发生报错,在这里首先储存好后续所需的 code,这里的code 可以获取用户唯一标识openid以及会话密钥sessionkey用于解密获取手机的加密信息
uni.login({
provider: 'weixin',
success: res => {
console.log(res)
this.login_code = res.code // 获得的code
}
});
以下操作最好交于后端操作,前端在开发阶段获取没问题,部署上去之后会报错,最后的全部代码里面我不会展示下面的代码操作
获取秘钥
通过 调用 https://api.weixin.qq.com/sns/jscode2session 微信接口获取到用户的信息,主要是要拿到openid 用户唯一标识和session_key 秘钥,后续解密手机号和登录需要用到
// let that = this
uni.request({
url: 'https://api.weixin.qq.com/sns/jscode2session',// 请求微信服务器
method:'GET',
data: {
appid: 'aaaaaaaaaaa' //你的小程序的APPID
secret: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', //你的小程序秘钥secret
js_code: this.login_code, //wx.login 登录成功后的code
grant_type:'authorization_code' // 固定写死的,不用变
,
success: (res) => {
// console.log('获取信息',res); // 换取成功后 暂存这些数据 留作后续操作
this.openid=res.data.openid //openid 用户唯一标识
this.session_key=res.data.session_key //session_key 会话密钥
// 这个请求时后端接口,联系后端储存信息用的,显然存不了什么信息,保存上面的信息就行,然后接受储存返回的token
this.$request({url:'/aa/aaaa/aaaaaaaaa',method:'post',data:{openid:this.openid,url:this.imgurl}}).then(res=>{
// 存储token
uni.setStorageSync('ACCESS_TOKEN',res.data.data.token)
this.form =res.data.data.user
that.$set(that,'form',res.data.data.user)
console.log(that.form,111,this.form)
})
}
});
获取手机号
利用getPhoneNumber方法获取手机号,通过 button 标签来实现,然后在methods方法里面来获取到数据,接受的参数是一个对象,对象里面的 detail 值就是后续解密之后的获取手机号的值,这里获取到的信息是最后必须得通过解密才能获取到的
<button type="warn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">授权登录</button>
getPhoneNumber(e){
// 如果点击授权进行下一步
if(e.detail.errMsg === 'getPhoneNumber:ok'){
this.getloginPhone = e.detail // 解密手机号所需的信息
this.show = true
}
}
手机号解密方法
下载引入解密文件地址 developers.weixin.qq.com/miniprogram…
使用
uniapp的话 那就下载node 即可 使用里面的 WXBizDataCrypt.js 文件即可
使用方法,把文件粘贴到项目文件中,引入使用即可
import WXBizDataCrypt from "@/utils/WXBizDataCrypt.js"; // 引入文件
let pc = new WXBizDataCrypt('aaaaaaaaaaaaa',session_key) // 执行解密操作,参数是,小程序appid和上面获取到的session_key秘钥
let data = pc.decryptData(this.getloginPhone.encryptedData,this.getloginPhone.iv) // 这里面所需的参数就是上面获取到的了,照填就可以
就此 data.phoneNumber 就是用户的手机号了
获取头像
这步就是通过 chooseAvatar 方法获取到用户头像信息,同时也可以选取相册照片当头像,一切看用户选择进行,同样也是通过button来进行的操作,方法参数是一个对象 里面的.detail.avatarUrl就是微信头像的临时地址,这时候可以通过uni.uploadFile方法储存到服务器上,因为这个临时地址只能在微信小程序里面打开在别的地方看不了,上传服务器代码最后完整代码里有展示,上传图片之前一定要在小程序上配置上传域名哦
<button type="warn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">授权头像</button>
onChooseAvatar(e) {
this.showing = true
let that = this
that.imgurl = e.detail.avatarUrl
}
获取用户昵称
这个方法其实就是弄个输入框,然后type和name 填写 nickname 就行
还有一点就是选择微信昵称的时候会出现不自动赋值的情况,这个时候可以使用 change 方法获取到变化的值,然后赋值上去即可
<input class="nicknamestyle" @change="inputBlur" v-model="natkName" type="nickname" placeholder="请输入昵称,不填则随机" name="nickname" />
//change事件方法
inputBlur(e){
this.natkName = e.detail.value
},
登录 把数据传给后端进行储存,并且接收返回的token存储下来用于后续请求操作
其实这一步骤在第一步的时候 获取秘钥的时候就有了,就是调接口然后返回token等用户数据,不过我的是自己的步骤进行的代码
let that = this
// 让后端处理,让后端向微信官方接口发送请求获取到用户数据,然后返回给我们
this.$request({url:'/aa/aaaaa/aaaaaaaaa',method:'post',data{js_code:this.login_code}}).then(res=>{
// 解密电话号码
let pc = new WXBizDataCrypt('aaaaaaaaaaaaaaaaaa',ress.data.data.session_key)
let data = pc.decryptData(this.getloginPhone.encryptedData,this.getloginPhone.iv)
//登录
this.$request({url:'/aa/aaaa/aaaaaaaaa',method:'post',data:openid:ress.data.data.openid,url:this.imgurl,phone:data.phoneNumber}}).then(res=>{
// 存储token和用户信息
uni.setStorageSync('ACCESS_TOKEN',res.data.data.token)
uni.setStorageSync('ACCESS_userInfo',JSON.stringify(res.data.data.user))
uni.showToast({
title:'登录成功',
icon:'none',
duration:1000
})
// 返回进来的地方
setTimeout(()=>{
uni.navigateBack()
},1000)
}).catch((rej)=>{
uni.showToast({
title:'获取信息失败,请重试',
icon:'none',
duration:1000
})
})
}).catch((rej)=>{
uni.showToast({
title:'获取信息失败,请重试',
icon:'none',
duration:1000
})
})
就此就结束了登录操作了
完整代码
<template>
<view>
<view class="box">
<view class="box-item">
<p class="item-title">授权</p>
<p class="item-p">授权信息同步订单和会员优惠</p>
<!-- <button :disabled="showing" class="btnstyle" style="width: 80%;border-radius: 40rpx;margin-top: 20rpx;" type="warn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">授权登录</button>
<button class="btnstyle" style="width: 80%;border-radius: 40rpx;margin-top: 20rpx;" @click="backIndex">返回首页</button> -->
</view>
<view class="infobox">
<view class="infoitem">
<view class="item-info">
<p class="info-p">昵称:</p>
<input class="nicknamestyle" @change="inputBlur" v-model="natkName" type="nickname" placeholder="请输入昵称,不填则随机" name="nickname" />
</view>
<view class="item-info">
<p class="info-p">头像:</p>
<img style="width: 80rpx;height: 80rpx;border-radius: 50%;" :src="imgurl || morenimg" alt="">
<button class="btnstyle" style="width: 180rpx;border-radius: 40rpx;height: 60rpx;font-size: 28rpx;margin: 0;" type="warn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">授权头像</button>
</view>
<!-- <view class="item-info">
<p class="info-p">手机号:</p>
<button class="btnstyle" style="width: 220rpx;border-radius: 40rpx;height: 60rpx;font-size: 28rpx;margin: 0;" type="warn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">授权手机号</button>
</view> -->
</view>
</view>
<button :disabled="showing" class="btnstyle" style="width: 80%;border-radius: 40rpx;margin-top: 20rpx;" type="warn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">授权登录</button>
<button class="btnstyle" style="width: 80%;border-radius: 40rpx;margin-top: 20rpx;" @click="backIndex">返回首页</button>
</view>
<!-- <u-popup :show="show" mode="center">
<view style="background-color: rgba(127, 127, 127,0);">
<input class="nicknamestyle" type="nickname" placeholder="请输入昵称" name="nickname" />
<button class="btnstyle" style="width: 600rpx;border-radius: 40rpx;" type="warn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">授权头像</button>
</view>
</u-popup> -->
<!-- 加载动画 -->
<u-loading-icon :show="showing"></u-loading-icon>
</view>
</template>
<script>
import WXBizDataCrypt from "@/utils/WXBizDataCrypt.js";
export default {
data() {
return {
getloginPhone:{}, // 登录手机号信息
login_code:null, //登录code
show:false, //微信头像授权弹窗
imgurl:null, // 头像地址
showing:false,
loginIng:false,// 登录状态
natkName:'',
morenimg:'https://jockers.oss-cn-beijing.aliyuncs.com/20230618/6f29d9cf438c496f8c130df0f83ecaa2.png'
};
},
onLoad() {
this.$store.commit('changeStopReuse',false)
this.login()
},
methods:{
getPhoneNumber(e){
// 如果点击授权进行下一步
if(e.detail.errMsg === 'getPhoneNumber:ok'){
if(!this.imgurl) return this.$showToast('请先获取头像')
this.getloginPhone = e.detail
this.showing = true
this.get_miyao()
}
},
inputBlur(e){
this.natkName = e.detail.value
},
onChooseAvatar(e) {
// this.showing = true
let that = this
// that.imgurl = e.detail.avatarUrl
// 获取图片信息
uni.getImageInfo({
src:e.detail.avatarUrl,
success(ress) {
// 存储头像
uni.uploadFile({
url:that.$store.state.imgUploadUrl+'/pc/file/upload',
filePath:ress.path,
name:'multipartFile',
header:{
'Authorization':uni.getStorageSync('ACCESS_TOKEN') ? 'Bearer '+ uni.getStorageSync('ACCESS_TOKEN'):'',
},
success(res) {
if(res.errMsg ==='uploadFile:ok'){
let img = JSON.parse(res.data).data
that.imgurl = img
// 清除token和用户信息
uni.clearStorageSync('ACCESS_TOKEN')
uni.clearStorageSync('ACCESS_userInfo')
uni.setStorageSync('ACCESS_userimg',that.imgurl)
return
}
},
fail(rej) {
// 如果报错也要执行
that.imgurl = e.detail.avatarUrl
// 清除token和用户信息
uni.clearStorageSync('ACCESS_TOKEN')
uni.clearStorageSync('ACCESS_userInfo')
uni.setStorageSync('ACCESS_userimg',e.detail.avatarUrl)
}
})
}
})
},
login(){
uni.login({
provider: 'weixin',
success: res => {
this.login_code = res.code // 获得的code
}
});
},
get_miyao(){ // 获取密钥 === 需要登录才可以获取密钥
let that = this
this.$request({url:'/aa/aaaa/aaaaaa',method:'post',data:{js_code:this.login_code}}).then(ress=>{
// 解密电话号码
let pc = new WXBizDataCrypt('aaaaaaaaaaaaa',ress.data.data.session_key)
let data = pc.decryptData(this.getloginPhone.encryptedData,this.getloginPhone.iv)
this.$request({url:'/aaaa/aaa/aaaaaa',method:'post',data:{openid:ress.data.data.openid,url:this.imgurl,phone:data.phoneNumber,nickName:this.natkName}}).then(res=>{
// 存储token
uni.setStorageSync('ACCESS_TOKEN',res.data.data.token)
uni.setStorageSync('ACCESS_userInfo',JSON.stringify(res.data.data.user))
that.$store.commit('addUserInfo',res.data.data.user)
uni.showToast({
title:'登录成功',
icon:'none',
duration:1000
})
// 返回进来的地方
setTimeout(()=>{
uni.navigateBack()
},1000)
}).catch((rej)=>{
uni.showToast({
title:'获取信息失败,请重试',
icon:'none',
duration:1000
})
this.showing = false
})
}).catch((rej)=>{
uni.showToast({
title:'获取信息失败,请重试',
icon:'none',
duration:1000
})
this.showing = false
})
},
backIndex(){
uni.switchTab({
url:'/pages/index/index'
})
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .u-popup__content{
background-color:rgba(127, 127, 127,0) !important;
}
.box{
.box-item{
margin-top: 40rpx;
text-align: center;
height: auto;
.item-title{
font-size: 36rpx;
font-weight: 800;
}
.item-p{
font-size: 36rpx;
color: #ababab;
}
}
.infobox{
display: flex;
justify-content: center;
padding: 40rpx;
.infoitem{
width: 600rpx;
.item-info{
display: flex;
align-items: center;
justify-content: space-between;
padding: 10rpx 0;
.info-p{
font-size: 28rpx;
font-weight: 700;
}
.nicknamestyle{
background-color: white;
border: 1px solid #ccc;
border-radius: 40rpx;
flex: 1;
text-align: center;
margin: 0 10rpx;
}
}
}
}
.btnstyle{
height: 85rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>