思路: 通过uni-app文档可知:实现微信登录,无论是app还是小程序,都需要唯一标识openid,然后通过openid取掉后端的登录接口,获取cookie然后做登录跳转;
【-【-【必须先调用微信的登录接口uni.login() 然后再去调用授权按钮拿微信个人信息】-】-】
(否则顺序错乱会导致 小概率授权后拿不到头像和昵称)
可直接复制以下代码使用(替换下图片@/static/iconimg/wxtu.png):
需要注意91和115行代码注释,在那里调后端两个接口,分别获取openid和登录的cookie;
<template><view class="page-login"><view v-if="canIUse||canIGetUserProfile"><view class='content'><image style="width: 140rpx; height: 140rpx;" mode="aspectFit" src="@/static/iconimg/wxtu.png"></image><view class="name">登录</view><view>申请获取以下权限</view><text>获得你的公开信息(昵称、头像、地区等)</text></view><view class="login-box"><!--新版登录方式--><button v-if="canIGetUserProfile" class='login-btn' type='primary' @click="bindGetUserInfo"> 授权登录 </button><!--旧版登录方式--><button v-else class='login-btn' type='primary' open-type="getUserInfo" withCredentials="true" lang="zh_CN" @getuserinfo="bindGetUserInfo"> 授权登录 </button></view></view><view v-else class="text-center">请升级微信版本</view></view>
</template>
<script>
export default {data () {return {canIUse: uni.canIUse('button.open-type.getUserInfo'),canIGetUserProfile: false,//微信登录新旧版本 true是新}},onLoad () {//必须先调用微信的登录接口 然后再去调用授权拿微信个人信息(否则顺序错乱会导致 小概率授权后拿不到头像和昵称)this.wxLogin()var _this = thisif (uni.getUserProfile) {this.canIGetUserProfile = true}},onShow () {},methods: {//登录授权bindGetUserInfo (e) {console.log('e', e)var _this = thisif (this.canIGetUserProfile) {//新版登录方式uni.getUserProfile({desc: '获取您个人信息用于登录!',success: (res) => {console.log('用户信息', res)// 存入个人信息uni.setStorageSync('userInfo_winxin', res.userInfo)_this.updateUserInfo()},fail: (res) => {console.log(res)}})} else {//旧版登录方式 --自动就拉起授权窗口if (e.detail.userInfo) {//用户按了允许授权按钮//console.log('手动');console.log('老版用户信息', e.detail.userInfo)// 存入个人信息uni.setStorageSync('userInfo_winxin', e.detail.userInfo)_this.updateUserInfo()} else {console.log('用户拒绝了授权')//用户按了拒绝按钮}}},//登录---目的拿到codewxLogin () {let _this = this// 获取登录用户codeuni.login({provider: 'weixin',success: function (res) {//console.log(res);if (res.code) {//将用户登录code传递到后台置换用户SessionKey、OpenId等信息 可参照此篇文章: https://ask.dcloud.net.cn/article/37452// 1.拿code调后端接口1 也就是getOpenid() 换取到SessionKey、OpenId(这个是唯一且固定不变)// 2.拿openId 调后端自己写的登录接口2 获取到cookie等信息 (这个cookie后期请求放在请求头上的) 登陆成功进行存储和跳转页面//这是我们的后端接口1--换取到SessionKey、OpenId// let params = { code: res.code}// getOpenid(params, false).then((res) => {// console.log('拿code调后端接口1 换取到SessionKey、OpenId', res)// uni.setStorageSync('session_key', res.data.session_key)// uni.setStorageSync('openid', res.data.openid)// })} else {uni.showToast({ title: '获取logon_code失败', duration: 2000 })console.log('获取logon_code失败' + res.errMsg)_this.wxLogin()}},fail: (res) => {uni.showToast({ title: '获取logon_code失败', duration: 2000 })console.log('获取logon_code失败' + res.errMsg)_this.wxLogin()}})},//向后台更新信息updateUserInfo () {let _this = this//这是我们的后端接口2--登录接口2 获取到cookie等信息(这个cookie后期请求放在请求头上的)// let params = {// openid: uni.getStorageSync('openid'),// nickname: uni.getStorageSync('userInfo_winxin').nickName,// head_image: uni.getStorageSync('userInfo_winxin').avatarUrl,// }// loginByWechat(params).then((res) => {// })//下面的这个cookie键值对是暂时写死的,正常应该接口2返回的let login_cookie_name = 'login_cookie_name'let login_cookie_value = 'login_cookie_value'uni.setStorageSync('login_cookie_name', login_cookie_name)uni.setStorageSync('login_cookie_value', login_cookie_value)// 注意:以上的存储为了在request请求时候携带和判断用 在退出登录时候需要清除掉uni.hideLoading()uni.showToast({title: '接口登录逻辑自写-登陆成功',duration: 1500,icon: 'success',})// 跳转到首页uni.reLaunch({ url: '/pages/index/index' })}}
}
</script><style lang="less" scoped>
.content {text-align: center;
}
</style>
但是获取openid的方式不同,目前有两个方式获取到。
注意一: 获取openid
1.通过uni.login()方法,得到code,拿这个code调用后端写的接口获取openid(此方式微信小程序和app都支持,H5不支持);如何通过code换取 session 和 openid/unionid
2.app还可以通过uni.getUserInfo 直接获取到openid
注意2: 获取用户信息方法有两种
1.需要注意,uni.getUserInfo是旧方法,它不支持新的版本,在新版本小程序里使用获取到的是默认信息无效的; 微信小程序端,在用户未授权过的情况下调用此接口,不会出现授权弹窗,会直接进入 fail 回调。在用户已授权的情况下调用此接口,可成功获取用户信息。
2.推荐使用uni.getUserProfile新的获取用户方法;每次请求都会弹出授权窗口,用户同意后返回 userInfo。
这张图是微信官方更新日志:
获取appId和AppSecret:
获取code方法:
获取用户信息的两个方法
uni-app微信登录app方法
uni-app微信登录微信小程序方法;以及登录后如何通过code换取 session 和 openid/unionid