const TOKEN_KEY = 'token'
|
const USER_KEY = 'appUserInfo'
|
const TOKEN_EXPIRE_AT_KEY = 'tokenExpireAt'
|
const LOGOUT_MODAL_KEY = 'showLogoutModal'
|
const REDIRECT_META_KEY = 'loginRedirectMeta'
|
const PENDING_PHONE_BIND_KEY = 'pendingPhoneBind'
|
|
/**
|
* 读取当前缓存中的 APP token。
|
*/
|
export function getStoredToken() {
|
const token = uni.getStorageSync(TOKEN_KEY)
|
return typeof token === 'string' ? token.trim() : ''
|
}
|
|
/**
|
* 判断当前是否存在本地登录态。
|
*/
|
export function hasStoredSession() {
|
return !!getStoredToken()
|
}
|
|
/**
|
* 判断当前是否存在完整 APP 登录态。
|
*/
|
export function hasCompletedAuthSession() {
|
return hasStoredSession() && hasBoundPhone() && !hasPendingPhoneBindSession()
|
}
|
|
/**
|
* 读取当前缓存中的 APP 用户信息。
|
*/
|
export function getStoredAppUser() {
|
const user = uni.getStorageSync(USER_KEY)
|
return user && typeof user === 'object' ? user : {}
|
}
|
|
/**
|
* 判断当前缓存用户是否已完成手机号绑定。
|
*/
|
export function hasBoundPhone() {
|
const user = getStoredAppUser()
|
return typeof user.phone === 'string' && user.phone.trim() !== ''
|
}
|
|
/**
|
* 判断当前缓存是否只是待绑定手机号的第三方临时会话。
|
*/
|
export function hasPendingPhoneBindSession() {
|
return uni.getStorageSync(PENDING_PHONE_BIND_KEY) === 1
|
}
|
|
/**
|
* 读取完整登录态可用的鉴权头;临时绑定会话不对普通业务接口暴露 token。
|
*/
|
export function getCompletedAuthHeader() {
|
if (!hasCompletedAuthSession()) {
|
return ''
|
}
|
return getStoredToken()
|
}
|
|
/**
|
* 从登录响应中持久化 APP 登录态。
|
*/
|
export function saveAuthSession(loginData, extras = {}) {
|
if (!loginData || typeof loginData !== 'object') {
|
return
|
}
|
persistSession(loginData, extras)
|
clearPendingBindSession()
|
}
|
|
/**
|
* 保存仅用于绑定手机号流程的第三方临时会话。
|
*/
|
export function savePendingBindSession(loginData, extras = {}) {
|
if (!loginData || typeof loginData !== 'object') {
|
return
|
}
|
persistSession(loginData, extras)
|
uni.setStorageSync(PENDING_PHONE_BIND_KEY, 1)
|
}
|
|
/**
|
* 清除待绑定手机号临时会话标记。
|
*/
|
export function clearPendingBindSession() {
|
uni.removeStorageSync(PENDING_PHONE_BIND_KEY)
|
}
|
|
/**
|
* 持久化 APP 会话公共字段。
|
*/
|
function persistSession(loginData, extras = {}) {
|
const tokenValue = typeof loginData.token === 'string' ? loginData.token.trim() : ''
|
if (tokenValue) {
|
const tokenType = typeof loginData.tokenType === 'string' && loginData.tokenType.trim() ? loginData.tokenType.trim() : 'Bearer'
|
uni.setStorageSync(TOKEN_KEY, `${tokenType} ${tokenValue}`.trim())
|
}
|
const userInfo = loginData.user && typeof loginData.user === 'object' ? loginData.user : {}
|
uni.setStorageSync(USER_KEY, {
|
...userInfo,
|
...extras.userOverrides,
|
})
|
uni.setStorageSync(LOGOUT_MODAL_KEY, 1)
|
persistTokenExpireAt(loginData.expiresIn)
|
if (extras.redirectMeta) {
|
uni.setStorageSync(REDIRECT_META_KEY, extras.redirectMeta)
|
}
|
}
|
|
/**
|
* 根据 expiresIn 持久化 token 预计过期时间戳。
|
*/
|
export function persistTokenExpireAt(expiresIn) {
|
const expireSeconds = Number(expiresIn)
|
// 后端 APP 永久 token 返回 -1,此时不保存过期时间,后续请求也不会触发定时刷新。
|
if (!Number.isFinite(expireSeconds) || expireSeconds <= 0) {
|
uni.removeStorageSync(TOKEN_EXPIRE_AT_KEY)
|
return
|
}
|
uni.setStorageSync(TOKEN_EXPIRE_AT_KEY, Date.now() + expireSeconds * 1000)
|
}
|
|
/**
|
* 读取当前 token 过期时间戳。
|
*/
|
export function getTokenExpireAt() {
|
const rawValue = Number(uni.getStorageSync(TOKEN_EXPIRE_AT_KEY) || 0)
|
return Number.isFinite(rawValue) && rawValue > 0 ? rawValue : 0
|
}
|
|
/**
|
* 判断当前 token 是否即将过期。
|
*/
|
export function willTokenExpireWithin(bufferMs = 0) {
|
const expireAt = getTokenExpireAt()
|
if (!expireAt) {
|
return false
|
}
|
return expireAt - Date.now() <= bufferMs
|
}
|
|
/**
|
* 清理本地 APP 登录态缓存。
|
*/
|
export function clearAuthSession() {
|
uni.removeStorageSync(TOKEN_KEY)
|
uni.removeStorageSync(USER_KEY)
|
uni.removeStorageSync(TOKEN_EXPIRE_AT_KEY)
|
uni.removeStorageSync(REDIRECT_META_KEY)
|
uni.removeStorageSync(PENDING_PHONE_BIND_KEY)
|
uni.setStorageSync(LOGOUT_MODAL_KEY, 0)
|
}
|