登录流程是调wx.login获取code传给后台服务器获取微信用户唯一标识openid及本次登录的会话密钥(session_key)等)。拿到开发者服务器传回来的会话密钥(session_key)之后,前端要保存wx.setStorageSync('sessionKey', 'value')
持久登录状态:session信息存放在cookie中以请求头的方式带回给服务端,放到 request.js 里的 wx.request 的header 里
核心:通过 vuex 的 hasLogin
来判断是进行后续操作,还是跳转到登录页
onLaunch
userInfo 和 userInfo.tel
openIdtelunionid
传给后端,换取最新 userInfo
,设置 hasLogin = true
openId
在不同应用下唯一unionid
在同一公司下,不同应用中唯一hasLogin = false
,清空 userInfo
,清空 token
wx.login
获取 wxCode
wxCode
、手机号iv
、手机号encryptedData
发给后端换取 token、tel、userInfohasLogin
auth
页面的方法getCurrentPages()[getCurrentPages().length - 1]
拿到当前页面onLaunch: function () {
this.wxLogin()
}
async wxLogin(context) {
let userInfo = storage.getUserInfo();
if (userInfo && userInfo.tel) {
// 有电话,以前登录过,更新 userInfo
const res = await user.doLoginMobile({
openid: userInfo.openidApp,
phone: userInfo.tel,
unionid: userInfo.unionid,
});
if (res.code === 0 && res.data) {
// 设置vuex登录状态
context.commit("setHasLogin", true);
context.commit("setUserInfo", res.data ? res.data : {});
context.commit("setToken", res.data ? res.data.token : "");
return context.state.userInfo;
} else {
// 登录失败
// 登出
context.commit("logout");
return false;
}
} else {
context.commit("logout");
return false;
}
},
// 登出
logout(state) {
state.userInfo = {};
state.hasLogin = false;
storage.removeUserInfo();
storage.removeToken();
},
// 手机号登录
async weChatLogin() {
// 获取code
this.wxCode = await this.getWxCode();
const data = {
code: this.wxCode, // 必传
IV: this.userData.iv, // 必传(手机号的iv)
encryptedData: this.userData.encryptedData, // 必传(手机号的encryptedData)
};
const res = await user.weChatLogin(data);
if (res.code === 0 && res.data) {
// 登录成功
this.setHasLogin(true);
this.$storage.setToken(res.data.token);
this.setUserInfo(res.data);
uni.showToast({ title: "授权登陆成功" });
setTimeout(() => {
this.jumpUrl(this.redirectUrl);
}, 500);
} else {
// 登录失败
uni.showModal({
title: "登录失败,请重试",
content: res.msg,
showCancel: false,
});
}
},
navigateTo
等跳转方法,使其除了接收 options
对象参数,还接受一个 needAuth
needAuth
为真,就看下 hasLogin
是否为真
// 对于需要登录才可以进入的页面,先做一下登录校验,如果未登录,则跳转前先跳转至登录页面。
import store from "@/store";
import { gotoAuth } from "@/utils/index";
// 对路由相关的几个方法进行遍历并缓存原方法,
// 在uni对象上重写方法,每个方法增加needAuth参数,表示跳转前是否需要登录
// 如果需要登录,则首先获取用户信息,
// 如果获取不到用户信息,将会自动跳转到登录页(store里面的user模块做的),
// 否则获取到信息就调用缓存起来的原方法,实现跳转 如果不需要登录,则直接调用原方法
export default function () {
["navigateTo", "redirectTo", "switchTab", "navigateBack"].map(item => {
const nativeFunc = uni[item];
uni[item] = function (opts, needAuth) {
if (needAuth) {
// store.dispatch("user/getToken").then(() => {
// nativeFunc.call(this, opts);
// });
if (store.state.hasLogin) {
nativeFunc.call(this, opts);
} else {
gotoAuth();
}
} else {
return nativeFunc.call(this, opts);
}
};
});
}
wx.getStorage/setStorage
支持任何原生类型,支持对象Date.now() - data.createTime > date.timeout