useAuth
简化 App 登录注册等授权操作。
Type Declarations
本系列方法用到的一些公共类型。
interface RequestResult {
isOk: boolean
msg: string
}
/**
* 登录结果
* @description 失败的话没有登录数据,会返回 `null`
*/
interface LoginResult extends RequestResult {
data: null | LoginInfo
}
tokenType
完整的 Token 需要包含 Token Type 作为开头,我们业务的 Token Type 固定为 Bearer
。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
type TokenType = 'Bearer'
- Example:
import { useAuth } from '@lunarxyz/core'
const { tokenType } = useAuth()
console.log(tokenType) // 'Bearer'
loginInfo
登录信息。
TIP
这里并不是直接导出一个响应式对象,而是通过 toRefs
导出了 Ref 变量,请见下方的 Example 。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
/**
* 登录信息,最终导出的是多个 Vue Ref 变量
*/
interface LoginInfo {
/**
* 用户 ID
*/
userId: string
/**
* 用户名
*/
username: string
/**
* 手机号码
*/
phoneNumber: string
/**
* 是否已设置密码
*/
hasPassword: boolean
/**
* 已包含凭证头的完整用户凭证
*/
token: Token
/**
* 用来刷新用户凭证有效期的凭证
*/
refreshToken: string
/**
* 几秒后过期
*/
expiresIn: number
/**
* 过期时间( 13 位时间戳)
*/
expiresIime: number
}
/**
* 用户凭证要么为空,要么是以 tokenType 开头
*/
type Token<T extends string> = `${TokenType} ${T}` | ''
- Example:
import { useAuth } from '@lunarxyz/core'
// 这里拿到的都是 Ref 响应式变量,必须用 `.value` 才能拿到正确的值
const { token, phoneNumber } = useAuth()
console.log({
token: token.value,
phoneNumber: phoneNumber.value,
})
// {
// "token": "Bearer 58f7*********************bc36",
// "phoneNumber": "13800138000"
// }
autoLogin
自动登录,会自动执行 getToken
-> login
-> register
等一系列流程。
如果其中有一个流程成功,则提前返回登录信息。
如果三个流程都失败,则返回空的登录信息,可以通过 isOk
来判断是否成功。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
/**
* 自动登录
*/
declare function autoLogin(options: AutoLoginOptions): Promise<LoginResult>
/**
* 自动登录选项
*/
interface AutoLoginOptions {
/**
* 手机号码
*/
phoneNumber: string
/**
* 登录验证码
*/
code: string
/**
* 是否跳过登录
* @description 如果知道手机号未注册,可以传 `true` 直接走注册流程
* @default false
*/
skipLogin?: boolean
/**
* 是否查询 Token
* @description 传 `true` 会先查一次 Token ,传 `false` 直接登录
* @default true
*/
queryToken?: boolean
/**
* 是否查询用户详情
* @description 会传递给 `getToken` ,详见该 API 的说明
*/
queryInfo?: boolean
/**
* 父级 ID
* @description 会传递给 `register` ,详见该 API 的说明
*/
parentId?: string
}
- Example:
import { ref } from 'vue'
import { useAuth, useSMS } from '@lunarxyz/core'
async function run() {
/**
* 需要先发送登录短信
* @description 实际业务请让用户手动触发,在手机上查收短信
*/
const phoneNumber = ref<string>('13800138000')
const { sendCode } = useSMS()
const { msg: loginCodeMsg } = await sendCode('login', phoneNumber.value)
if (loginCodeMsg.includes('未注册')) {
await sendCode('register', phoneNumber.value)
}
/**
* 再执行自动登录并获取登录信息
* @description 这里的验证码需要让用户输入后才拿到
*/
const { autoLogin } = useAuth()
const { isOk, msg, data } = await autoLogin({
phoneNumber: phoneNumber.value,
code: '123456',
queryToken: true,
parentId: '88',
})
console.log({ isOk, msg, data })
// {
// "isOk": true,
// "msg": "",
// "data": {
// "userId": "123",
// "username": "13800138000",
// "phoneNumber": "13800138000",
// "hasPassword": false,
// "token": "Bearer f3e7*********************0ce9",
// "refreshToken": "",
// "expiresIn": 0,
// "expiresIime": 0
// }
// }
}
run().catch((e) => {
console.log(e)
})
getToken
获取有效期内的 Token 。
TIP
获取 Token 之前,必须发送一次验证码才可以,该方法走 登录流程 获取验证码。
WARNING
如果通过该方法拿到 Token ,会请求用户详情刷新部分用户信息(但不包括 expiresIn
、 expiresIime
、 hasPassword
、 refreshToken
这 4 个数据,所以该方法仅建议在不需要这 4 个数据的活动页面使用,如果需要这 4 个数据,请直接走登录流程。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
/**
* 获取有效期内的 Token
*/
declare function getToken(options: GetTokenOptions): Promise<LoginResult>
/**
* 获取 Token 选项
*/
interface GetTokenOptions {
/**
* 手机号码
*/
phoneNumber: string
/**
* 登录验证码
*/
code: string
/**
* 是否查询用户详情
* @description 默认会查询一次 memberinfo ,传 `false` 则不查,可以另外手动请求
* @default true
*/
queryInfo?: boolean
}
- Example:
import { ref } from 'vue'
import { useAuth, useSMS } from '@lunarxyz/core'
async function run() {
/**
* 需要先发送登录短信
* @description 实际业务请让用户手动触发,在手机上查收短信
*/
const phoneNumber = ref<string>('13800138000')
const { sendCode } = useSMS()
await sendCode('login', phoneNumber.value)
/**
* 再执行获取 Token 以及登录信息
* @description 这里的验证码需要让用户输入后才拿到
*/
const { getToken } = useAuth()
const { isOk, msg, data } = await getToken({
phoneNumber: phoneNumber.value,
code: '123456',
queryInfo: false,
})
console.log({ isOk, msg, data })
// {
// "isOk": true,
// "msg": "",
// "data": {
// "userId": "123",
// "username": "13800138000",
// "phoneNumber": "13800138000",
// "hasPassword": false,
// "token": "Bearer f3e7*********************0ce9",
// "refreshToken": "",
// "expiresIn": 0,
// "expiresIime": 0
// }
// }
}
run().catch((e) => {
console.log(e)
})
login
App 登录,支持验证码登录和账号密码登录。
TIP
执行登录之前,必须发送一次登录验证码才可以。
登录成功后,接口响应回来的数据会自动更新给响应式的 loginInfo
,并更新本地存储。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
/**
* 登录
*/
declare function login(options: LoginOptions): Promise<LoginResult>
/**
* 登录选项
*/
interface LoginOptions {
/**
* 登录类型,目前只支持验证码和密码登录
*/
type: 'code' | 'password'
/**
* 手机号码
*/
phoneNumber: string
/**
* 验证码, `type` 为 `code` 时必传
*/
code?: string
/**
* 登录密码, `type` 为 `password` 时必传
*/
password?: string
}
- Example:
import { ref } from 'vue'
import { useAuth, useSMS } from '@lunarxyz/core'
async function run() {
/**
* 需要先发送登录短信
* @description 实际业务请让用户手动触发,在手机上查收短信
*/
const phoneNumber = ref<string>('13800138000')
const { sendCode } = useSMS()
await sendCode('login', phoneNumber.value)
/**
* 再执行登录并获取登录信息
* @description 这里的验证码需要让用户输入后才拿到
*/
const { login } = useAuth()
const { isOk, msg, data } = await login({
type: 'code',
phoneNumber: phoneNumber.value,
code: '123456',
})
console.log({ isOk, msg, data })
// {
// "isOk": true,
// "msg": "",
// "data": {
// "userId": "123",
// "username": "13800138000",
// "phoneNumber": "13800138000",
// "hasPassword": true,
// "token": "Bearer f3e7*********************0ce9",
// "refreshToken": "a5a8f144-6806-474c-bd7c-7cb7ca550b9f",
// "expiresIn": 43199,
// "expiresIime": 1658695221652
// }
// }
}
run().catch((e) => {
console.log(e)
})
register
App 注册,注册成功后会返回登录信息。
TIP
执行注册之前,必须发送一次注册验证码才可以。
注册成功后,接口响应回来的数据会自动更新给响应式的 loginInfo
,并更新本地存储。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
/**
* 注册
*/
declare function register(options: RegisterOptions): Promise<LoginResult>
/**
* 注册选项
*/
interface RegisterOptions {
/**
* 手机号码
*/
phoneNumber: string
/**
* 验证码
*/
code: string
/**
* 密码
*/
password?: string
/**
* 二次确认密码
*/
confirmPassword?: string
/**
* 父级 ID
* @description 如果有拉新需求,这里传入邀请人的用户 ID
*/
parentId?: string
}
- Example:
import { ref } from 'vue'
import { useAuth, useSMS } from '@lunarxyz/core'
async function run() {
/**
* 需要先发送注册短信
* @description 实际业务请让用户手动触发,在手机上查收短信
*/
const phoneNumber = ref<string>('13800138000')
const { sendCode } = useSMS()
await sendCode('register', phoneNumber.value)
/**
* 再执行注册并获取登录信息
* @description 这里的验证码需要让用户输入后才拿到
*/
const { register } = useAuth()
const { isOk, msg, data } = await register({
phoneNumber: phoneNumber.value,
code: '123456',
password: '11111111',
confirmPassword: '11111111',
})
console.log({ isOk, msg, data })
// {
// "isOk": true,
// "msg": "",
// "data": {
// "userId": "123",
// "username": "13800138000",
// "phoneNumber": "13800138000",
// "hasPassword": true,
// "token": "Bearer f3e7*********************0ce9",
// "refreshToken": "a5a8f144-6806-474c-bd7c-7cb7ca550b9f",
// "expiresIn": 43199,
// "expiresIime": 1658695221652
// }
// }
}
run().catch((e) => {
console.log(e)
})
saveLoginInfo
保存登录信息,用于登录或者注册后,把接口响应回来的数据更新给响应式的 loginInfo
,并更新本地的 Storage 信息。
WARNING
一般情况下无需手动调用,在登录、注册等环节会自动执行。
导出该方法只是为了给需要手动处理的特殊情况使用。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
declare function saveLoginInfo(
/**
* 登录成功后接口返回的登录信息
*/
res: any
): LoginInfo
restoreLoginInfo
回显登录信息,可以从本地存储恢复登录信息,避免每次刷新页面就失去登录状态。
TIP
建议在入口文件( App.vue
/ main.ts
)调用,比其他接口请求先执行。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
declare function restoreLoginInfo(): void
- Example:
import { useAuth } from '@lunarxyz/core'
const { restoreLoginInfo } = useAuth()
restoreLoginInfo()
isTokenExpired
判断 Token 是否已过期,会调用一次用户详情接口来判断 Token 是否真的无效,所以它是一个异步函数。
之所以这样做,是因为 expiresIime
可能不准确,例如顶号等行为会让 Token 提前失效。
- Supported Platforms:
Browser | Electron | App | Server | Scriptlet |
- Type Declarations:
declare function isTokenExpired(): Promise<boolean>
- Example:
import { useAuth } from '@lunarxyz/core'
async function run() {
const { isTokenExpired } = useAuth()
const isExpired = await isTokenExpired()
if (isExpired) {
console.log('Token 失效')
// 操作一些引导登录的行为
}
}
run().catch((e) => {
console.log(e)
})