一、先看一下如何使用
- login:登陆过返回用户信息,没有登陆过执行登陆逻辑
- loginForce:强制登陆
import {login, loginForce} from '@/utils/login'
async function needLoginFn() {
await login()
}
async function toRrefreshLogin() {
await loginForce()
}
复制代码
二、完整微信小程序登陆逻辑
import setting from '@/utils/setting'
import authority from '@/utils/authority'
import request from '@/utils/request/doRequest'
import { redirectLogin } from '@/utils/router'
let prevCodeLogin
async function validateSetting() {
const hasSetting = await setting.has('userInfo')
if (!hasSetting) {
authority.clear()
redirectLogin()
}
return hasSetting || handleError(new Error('没有获取UserInfo权限'))
}
export function validateSession() {
return new Promise(resolve => {
wx.checkSession({
success() {
resolve(1)
},
fail() {
resolve(0)
}
})
})
}
export async function codeLogin(force) {
const cacheUser = authority.get() || {}
if (!force && cacheUser.id) return cacheUser
const isValid = await validateSession()
if (force || !isValid) {
if (prevCodeLogin) return prevCodeLogin
prevCodeLogin = new Promise((resolve, reject) => {
wx.login({
async success({ code }) {
try {
const res = await request({
url: '/api/client/v1/auth/session',
method: 'post',
data: { code }
})
const { user = {}, token } = res
user.token = token
authority.set(user)
prevCodeLogin = null
return resolve(user)
} catch (e) {
reject(e)
}
},
fail(e) {
prevCodeLogin = null
reject(e)
}
})
})
return prevCodeLogin
}
return cache
}
export async function toDecode({ encrypted_data, iv }) {
const { user, token } = await request({
url: '/api/client/v1/auth/login',
method: 'post',
data: {
encrypted_data,
iv
}
})
if (user) {
user.token = token
authority.set(user)
return user
} else {
return Promise.reject(new Error('登录decode失败'))
}
}
export function decodeUserInfo() {
return new Promise(resolve => {
wx.getUserInfo({
lang: 'zh_CN',
async success(res) {
const { encryptedData, iv } = res
const user = await toDecode({
encrypted_data: encryptedData,
iv
})
resolve(user)
}
})
})
}
export async function login() {
const user = await codeLogin()
if (user.id) {
return user
}
await validateSetting()
return decodeUserInfo()
}
export async function loginForce() {
authority.clear()
await login()
}
复制代码
三:附录:所用工具类
authority:简单封装localStorage
const key = 'prefix_key'
const maxAge = 1000 * 60 * 60 * 24 * 60
export default {
get() {
try {
const user = wx.getStorageSync(key)
if (!user || user.time + maxAge < new Date().getTime()) return {}
return user || {}
} catch (e) {
return {}
}
},
set(user) {
if (!user) return null
user.time = new Date().getTime()
const oldUser = this.get() || {}
const newUser = { ...oldUser, ...user }
wx.setStorageSync(key, newUser)
return newUser
},
clear() {
const user = this.get() || {}
wx.clearStorageSync()
wx.removeStorageSync(key)
this.set({ user: {} })
return user
}
}
复制代码
setting:用户设置简单封装
const noop = () => {}
let preGetSetting
export function openSetting(name, callback = noop) {
wx.getSetting({
success({ authSetting }) {
const key = `scope.${name}`
let success = false
if (authSetting[key] === false) {
wx.show
wx.openSetting({
success({ authSetting: auth }) {
if (callback) {
success = auth[key] !== false
callback(success)
}
}
})
} else {
if (typeof callback === 'function') {
callback(success)
}
}
}
})
}
export function getSetting() {
if (preGetSetting) return preGetSetting
preGetSetting = new Promise(resolve => {
wx.getSetting({
success({ authSetting }) {
preGetSetting = null
resolve(authSetting)
},
fail(e) {
preGetSetting = null
reject(e)
}
})
})
return preGetSetting
}
async function hasSetting(name) {
const setting = await getSetting()
const key = `scope.${name}`
return setting[key]
}
export default {
open: openSetting,
get: getSetting,
has: hasSetting
}
复制代码