Skip to content

Auth 模块 (登录/用户)

Auth 模块基于 @makeblock/passport-client 构建,因此开发者无需自行实现登录逻辑。

API 列表

方法返回值描述
sdk.auth.getStatus()AuthStatus从本地缓存同步获取当前登录状态
sdk.auth.login()Promise<UserInfo>打开登录弹窗,成功后返回用户信息
sdk.auth.logout()Promise<void>退出登录并清除本地 token
sdk.auth.onChange(callback)() => void监听状态变化,返回取消订阅函数
sdk.auth.getToken()string获取当前 uToken;未登录时返回空字符串
sdk.auth.syncToken(token)Promise<AuthStatus>持久化外部传入的 token,并刷新登录状态

详细用法

获取当前状态

typescript
const status = sdk.auth.getStatus()
// { isLogin: boolean, userInfo: UserInfo | null }

if (status.isLogin) {
  console.log('用户名:', status.userInfo!.userName)
  console.log('头像:', status.userInfo!.headpic)
  console.log('邮箱:', status.userInfo!.email)
}

弹窗登录

typescript
try {
  const userInfo = await sdk.auth.login()
  console.log('登录成功:', userInfo.userName)
} catch (err) {
  // 用户关闭了弹窗或登录失败
  console.log('登录取消或失败:', err.message)
}

退出登录

typescript
await sdk.auth.logout()
// 本地 token 已清除,且 passport-client 已调用退出登录 API

监听状态变化

typescript
const unsubscribe = sdk.auth.onChange((status) => {
  if (status.isLogin) {
    showUserInfo(status.userInfo!)
  } else {
    showLoginButton()
  }
})

// 在组件卸载时取消订阅
unsubscribe()

获取原始 Token

typescript
const token = sdk.auth.getToken()
// 可用于开发者自行实现的自定义 API 请求

同步外部 Token

typescript
await sdk.auth.syncToken(token)
// token 会写入本地存储,并刷新当前登录状态

await sdk.auth.syncToken('')
// 传入空 token 会清空本地登录态,并返回 { isLogin: false, userInfo: null }

Studio 内嵌登录态同步

SDK 初始化后会默认尝试同步 xTool Studio 注入的登录态,无需生成器额外调用 syncToken()

  • 无界微前端:读取 window.$wujie.props.token,并监听 window.$wujie.busUserStateChanged 事件。
  • iframe 内嵌:读取 window.frameElement 上的 data-initial 初始值,并监听可信 Studio 来源发送的 postMessage({ eventName: 'UserStateChanged', payload: { token } }),包括 Studio Electron 的 atomm://renderer
  • Studio 下发空 token 时,SDK 会清空本地登录态并触发 onChange()

该同步复用 syncToken() 的内部流程:写入 utoken Cookie、通过 passport-client 拉取用户信息、请求角色列表,并触发登录状态变化。

角色信息

登录成功或执行 syncToken() 后,SDK 还会请求 /efficacy/v1/roles?d=xtool 获取角色列表。

typescript
const userInfo = await sdk.auth.login()

console.log(userInfo.roleList)
// 示例: [{ code: 'community_admin', name: 'Community Admin' }]

console.log(userInfo.isCommunityAdmin)
// 当 roleList 中存在 code === 'community_admin' 时为 true

UserInfo 类型

typescript
interface UserRole {
  code: string
  [key: string]: unknown
}

interface UserInfo {
  uid: number              // 用户 ID
  uuid: string             // 用户 UUID
  userName: string         // 用户名 (注意:不是昵称)
  headpic: string          // 头像 URL
  email: string            // 邮箱
  phoneNumber: string      // 电话号码
  phoneZone: string        // 电话国家/地区代码
  gender: number           // 性别: 0=未知 / 1=男 / 2=女
  signature: string        // 个人签名
  createTime: number       // 账号创建时间 (Unix 秒)
  roleList: UserRole[]     // 从 /efficacy/v1/roles?d=xtool 获取的角色列表
  isCommunityAdmin: boolean // roleList 中是否包含 code === 'community_admin'
}

interface AuthStatus {
  isLogin: boolean
  userInfo: UserInfo | null
}

内部登录流程

① 调用 sdk.auth.login()
② passport-client.openModal() 打开登录弹窗
③ 用户使用账号密码或二维码登录
④ 回调接收 token → setToken(appKey, token) 将其写入本地存储
⑤ passportClient.userInfo() 获取用户信息以验证 token 有效性
⑥ /efficacy/v1/roles?d=xtool 拉取角色信息
⑦ 内部 _setLoginStatus() 更新状态并触发 onChange 回调
⑧ login() resolve 返回 UserInfo

自动 Token 恢复

当 SDK 初始化时,它会依次运行本地恢复和 Studio 宿主同步:

  1. 从本地存储读取 token
  2. 如果存在 token,调用 passportClient.userInfo() 进行验证
  3. 如果验证成功,设置登录状态并触发 onChange
  4. 如果验证失败,清除无效的 token
  5. 如果当前页面内嵌在 xTool Studio 中,再读取 Studio 初始 token 并以 Studio 登录态为准
  6. 初始化后继续监听 Studio 的 UserStateChanged,保持生成器登录态与 Studio 主应用一致

WARNING

恢复过程是异步的。在 init() 返回后,getStatus() 可能仍报告未登录,因此请监听 onChange 以获取最终状态。

错误处理说明

  • login() 在登录回调返回空 token 时会 reject。
  • syncToken() 传入空 token 时会直接清空本地状态并返回未登录态。
  • syncToken() 在拉取用户信息失败时会先清理本地状态,再继续抛出错误。
  • logout() 即使远端退出失败,也会保证本地状态被清理。

MIT Licensed