如下图:用户授权登录前,先通过静默授权,拿到token,展示部分信息,用户通过授权后拿到头像昵称,该弹窗让用户有个比较好的体验
请求过程如下:
1、首次在没有UID、code的情况下:静默授权(&scope=snsapi_base)-->微信带回code,App.vue通过code调取服务端接口(code2session)获取token、openid,此时还拿不到用户头像、昵称
2、前端展示页,显示如下图用户授权弹窗,用户点击允许授权(&scope=snsapi_userinfo),同时设置过期时间(还未拿到头像昵称),调用(code2session)服务端拿到用户头像昵称,微信地址还是会带回code,调用服务端接口获取用户信息。
3、如果用户登录过期时,前端界面通过过期验证弹出出授权弹窗,用户允许授权,直接调用服务端获取用户信息接口即可。
,
展示界面部分代码:
1、标签
<template>
<!--遮罩-->
<view v-if="showAuth"
style="background-color:rgb(0 0 0 / 8%);position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: 999;"
@click="handelLogin">
<view class="author-view">
<view>
<image class="author-title-img" src="../../static/img/gologin.gif"></image>
</view>
<view>为了让您获得更好浏览体验</view>
<view>请先进行微信授权</view>
<view class="author-title-btn">
<view>去授权</view>
</view>
</view>
</view>
</template>
2、js
<script>
import tool from '@/common/utils/tool.js'
export default {
data() {
return {
showAuth: false,
lastLocal: '',
isReplace: false
}
},
methods: {
handelLogin() {
this.$store.commit('CLEAR_CWZ_USER_INFO')
const APPID = this.$config.AppId
var local = window.location.href //tool.local.get('init_local')
var lastLocal = local
//lastLocal :静默授权后回调地址会返回code,当用户同意授权后回调地址还会拼接code,这里将现有路径上的所有的code去掉,再复制给回调地址,以保证code是最新的
let strsArr = local.split('?'); //将字符串内容以&分隔为一个数组
if (strsArr.length >= 2) {
let str_back = local.substr(local.indexOf('?')); //截取?后面的内容作为字符串
let strs = str_back.split('#/'); //将字符串内容以&分隔为一个数组
if (strsArr.length == 2) {
// lastLocal = strsArr[0] + strs[strs.length - 1]
var lastStr = strs[strs.length - 1]
var lastStr_arr = lastStr.split('?')
if (strs.length >= 2) {
lastLocal = strsArr[0] + '#/' + strs[strs.length - 1]
} else {
lastLocal = strsArr[0] + strs[strs.length - 1]
}
} else {
lastLocal = strsArr[0] + '#/' + strs[strs.length - 1]
}
}
// this.$store.commit('CLEAR_CWZ_USER_INFO')
// this.showAuth = false;//允许授权后关闭授权遮罩
var loginDate = new Date().getTime()
tool.local.set('lastLoginDate', loginDate)
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + APPID +
'&redirect_uri=' +
encodeURIComponent(lastLocal) +
'&response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect'
},
},
onShow() {
},
mounted() {
//授权获取用户信息
var self = this
var lastLoginDate = tool.local.get('lastLoginDate') //过期时间戳
if (lastLoginDate) { // 已登录过,判断是否过期
var nowDate = new Date().getTime()
var interval = (nowDate - lastLoginDate) / (60 * 60 * 1000)
//var interval = (nowDate - lastLoginDate) / (60 * 1000) //测试 大于10秒就算过期
if (interval >= 24) { // 过期
//if (interval >= 5) { // 过期
this.showAuth = true;
tool.local.del('lastLoginDate')
} else {
this.showAuth = false; //允许授权后关闭授权遮罩
}
} else { // 没有登录过 且还未重定向
//this.$store.commit('CLEAR_CWZ_USER_INFO')
this.showAuth = true;
}
}
}
</script>
3、css
/**底部授权*/
.author-view {
position: fixed;
bottom: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background: linear-gradient(transparent, #FFF, #FFF, #FFF);
z-index: 999;
color: #000;
padding: 30px 0;
}
.author-title-btn {
background-color: #1373ff;
color: #fff;
padding: 10px 70px;
border-radius: 20px;
margin-top: 20px;
}
.author-title-img {
width: 50px;
height: 50px;
margin-bottom: 10px;
}
App.vue执行过程
local:地址也要处理下,把微信回调的地址自动拼接的code掉
if (!userId) {
self.$store.commit('CLEAR_CWZ_USER_INFO')
if (!code) {
//新用户进来静默授权
window.location.href =
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' +
APPID +
'&redirect_uri=' +
encodeURIComponent(local) +
'&response_type=code&scope=snsapi_base&state=1&connect_redirect=1#wechat_redirect';
} else {
//授权回调,已经拿到code,走code2session
self.setupWxSDK(APPID, url);
if (code_local !== code) {
self.code2Session(code, local)
} else {
//点击授权后,拒绝授权,返回上一页重新静默授权
window.location.href =
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' +
APPID +
'&redirect_uri=' +
encodeURIComponent(local) +
'&response_type=code&scope=snsapi_base&state=1&connect_redirect=1#wechat_redirect';
}
}
} else {
//有userid的情况
// TODO 有缓存的用户信息,没有过期,并且信息完全,不需要跳转授权的情况,直接进入系统
var headimgurl = tool.local.get('headimgurl')
var nickName = tool.local.get('nickName')
if (lastLoginDate && headimgurl && nickName) {
var nowDate = new Date().getTime() // (nowDate - lastLoginDate) 两个时间的毫秒数差值
//1000毫秒=1秒 60*60*1000代表1小时 ,
var interval = (nowDate - lastLoginDate) / (60 * 60 * 1000)
//var interval = (nowDate - lastLoginDate) / (60 * 1000) //测试 大于10秒就算过期
if (interval >= 24) { // 过期
//if (interval >= 5) { // 过期
} else {
self.setupWxSDK(APPID, url);
//获取用户信息
this.selectUserAndGptInfo(userId)
}
} else if (code) {
self.setupWxSDK(APPID, url);
//授权回调,已经拿到code,走code2session
if (code_local !== code) { //code唯一,不能重复提交
tool.local.set('code_local', code)
self.code2Session(code, local)
}
}
}