NocoBase 前端 SDK Auth 完全指南:登录、登出与 Token 管理
【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase
导读
Auth是 NocoBase 前端 SDK(@nocobase/sdk)中负责用户认证的核心类,它封装了登录(signIn)、注册(signUp)、注销(signOut)等认证接口调用,并在本地持久化用户的语言、角色、认证器与 API Token,同时通过 axios 请求拦截器为每一次 API 请求自动附加认证与上下文请求头。本文以官方 API 文档 docs/docs/cn/api/sdk/auth.md 为骨架,结合 packages/core/sdk/src/Auth.ts 等源码与测试用例,完整讲解Auth的实例属性、类方法、底层存储与拦截器机制,帮助你掌握在 NocoBase 二次开发中正确使用 SDK 完成用户认证的全套实战方案。
概览:Auth 类在 SDK 中的定位
Auth类主要用于在客户端存取用户信息,并请求用户认证相关的接口。在 NocoBase 前端 SDK 中,Auth并非独立使用,而是作为 APIClient 的一个实例属性存在(api.auth)。当APIClient被创建时,会自动实例化Auth并注册请求拦截器:
constructor(api: APIClient) { this.api = api; this.api.axios.interceptors.request.use(this.middleware.bind(this)); }这段代码位于 Auth.ts,意味着从APIClient创建那一刻起,后续所有经由此 axios 实例发出的请求都会经过Auth的middleware处理,自动携带认证相关的请求头。因此,Auth是 NocoBase 前端所有需要登录态请求的"守门员"。
此外,Auth是一个可扩展的基类:APIClient支持通过authClass配置项替换默认的Auth实现,例如接入自定义的第三方登录协议,详见下文"自定义 Auth 子类"一节。
实例属性:locale、role、token 与 authenticator
Auth暴露四个核心实例属性,分别对应当前用户的语言、角色、API Token 与认证器。这四个属性都有对应的 getter 与 setter,底层通过getOption/setOption读写APIClient的 storage(默认是localStorage):
| 属性名 | 类型 | 说明 | 底层存储 Key |
|---|---|---|---|
locale | string | 当前用户使用的语言 | locale |
role | string | 当前用户使用的角色 | role |
token | string | API 接口 token(Bearer Token) | token |
authenticator | string | 当前用户认证时所用的认证器标识 | auth |
注意:
authenticator对应的存储 key 是auth而非authenticator,这是源码中 getAuthenticator() 直接返回this.getOption('auth')的结果。
存储机制与命名空间
Auth的读写最终落在 Storage.ts 中的BaseStorage实现上。APIClient默认使用LocalStorage,key 统一由storagePrefix(默认'NOCOBASE_')加属性名大写拼接而成,例如:
NOCOBASE_TOKEN:tokenNOCOBASE_AUTH:认证器NOCOBASE_LOCALE:语言NOCOBASE_ROLE:角色
在测试用例 api-client.test.ts 中可以验证这一行为:执行signIn之后,localStorage.getItem('N1_TOKEN')返回登录接口下发的 token,localStorage.getItem('N1_AUTH')返回认证器标识。
当指定了appName时,存储前缀会变为${storagePrefix}${appName.toUpperCase()}_(见 APIClient.ts),例如appName: 'myApp'时 token 存于NOCOBASE_MYAPP_TOKEN,从而实现多应用间存储隔离。
role 与 Cookie 的联动
与其它属性不同,设置role除了写入 storage,还会同步写入浏览器 Cookie。源码 setRole() 调用setRoleCookie,而 auth-cookie.ts 中的实现会写入形如role_<appName>=<role>的 Cookie(SameSite=Lax,HTTPS 下附加Secure),并支持通过Path与部署的 public path 对齐。当角色被置空(登出)时,该 Cookie 会以Max-Age=0被立即清除。测试用例 api-client.test.ts 验证了带appName命名空间的角色 Cookie 写入与清除行为。
token 变更事件
设置token时,Auth还会通过api.app.eventBus派发一个auth:tokenChanged的自定义事件(Auth.ts),事件detail中包含新的token与authenticator。这意味着应用其它模块可以监听该事件实时响应登录态变化,例如刷新用户信息或跳转页面。
请求拦截器:自动附加认证请求头
Auth的核心价值之一,是middleware拦截器(Auth.ts)在每次请求发出前自动附加以下请求头:
| 条件 | 附加的请求头 | 值 |
|---|---|---|
已设置locale | X-Locale | 当前语言 |
已设置role | X-Role | 当前角色 |
已设置authenticator且未显式指定 | X-Authenticator | 认证器标识 |
已设置token且未显式指定 | Authorization | Bearer <token> |
非安全方法(非get/head/options)且有 CSRF Cookie | X-CSRF-Token | Cookie 中的csrfToken |
其中SAFE_METHODS = new Set(['get', 'head', 'options']),即只有写操作(post、put、delete等)才会附加 CSRF Token,这是 headers.ts 中hasHeaderValue与auth-cookie.ts中getAuthCookieValue('csrfToken', appName)配合实现的防重放保护。
测试用例 api-client.test.ts 中的syncCookies用例验证了拦截器行为:设置 token 后发出的请求携带Authorization: Bearer 123请求头。由于这些请求头在每个请求上自动附加,业务代码无需手动拼接认证信息,只需确保登录后token等属性已正确写入即可。
类方法详解
signIn():用户登录
签名
async signIn(values: any, authenticator?: string): Promise<AxiosResponse<any>>参数
| 参数名 | 类型 | 描述 |
|---|---|---|
values | any | 登录接口请求参数,如{ email, password }或{ username, password } |
authenticator | string | 登录使用的认证器标识,如basic、password或第三方认证器名称 |
源码行为(Auth.ts)
signIn会向auth:signIn动作发起 POST 请求,并在请求头中携带X-Authenticator指定认证器。请求成功后,从响应体response.data.data中取出服务端签发的token,依次执行:
this.setAuthenticator(authenticator):将认证器标识持久化;this.setToken(data?.token):将 token 持久化并触发auth:tokenChanged事件。
因此登录成功后,后续所有请求都会通过拦截器自动携带Authorization: Bearer <token>与X-Authenticator。测试用例(api-client.test.ts)完整验证了这一流程:mock 返回{ data: { token: '123' } }后,api.auth.getToken()与localStorage中的值均为'123'。
典型用法
const response = await api.auth.signIn( { email: 'admin@nocobase.com', password: 'your-password' }, 'basic', ); // 登录成功后 token 已自动持久化,可直接发起业务请求 const data = await api.resource('users').list();signUp():用户注册
签名
async signUp(values: any, authenticator?: string): Promise<AxiosResponse<any>>参数
| 参数名 | 类型 | 描述 |
|---|---|---|
values | any | 注册接口请求参数,如邮箱、密码、昵称等 |
authenticator | string | 注册使用的认证器标识 |
signUp向auth:signUp动作发起 POST 请求(Auth.ts)。与signIn不同,signUp本身不会自动写入 token——是否需要在注册后自动登录,取决于具体业务(可注册后调用signIn完成登录态建立)。
signOut():注销登录
签名
async signOut(values: any, authenticator?: string): Promise<AxiosResponse<any>>参数
| 参数名 | 类型 | 描述 |
|---|---|---|
values | any | 注销接口请求参数 |
authenticator | string | 注销使用的认证器标识 |
signOut向auth:signOut动作发起 POST 请求(Auth.ts),并在请求完成后执行清理:
this.setToken(null):清除本地 token;this.setRole(null):清除角色 storage 与角色 Cookie;this.setAuthenticator(null):清除认证器标识。
从而完整移除本地登录态。业务中通常会在"退出登录"按钮中调用它,随后跳转到登录页。
其它实用方法(文档之外的补充)
除了官方文档列出的三个方法,源码还提供了四个与密码找回、登录态同步相关的方法:
| 方法 | 请求动作 | 说明 |
|---|---|---|
syncCookies() | auth:syncCookies | 已有 token 时调用,用于将登录态同步到 Cookie(多端/多应用场景);无 token 时直接返回undefined |
lostPassword(values) | auth:lostPassword | 发送找回密码邮件,自动从当前 URL 提取baseURL与认证器查询参数 |
resetPassword(values) | auth:resetPassword | 重置密码 |
checkResetToken(values) | auth:checkResetToken | 校验重置密码用的 token 是否有效 |
这些方法均以auth:<action>的动作命名发起请求,与 NocoBase 服务端动作路由一一对应。
自定义 Auth 子类:接入自有认证协议
APIClient的构造参数支持authClass,允许你用自定义类替换默认Auth实现。官方测试给出了一个标准范例(api-client.test.ts):
import { APIClient, Auth } from '@nocobase/sdk'; class TestAuth extends Auth { async signIn(values: any) { const response = await this.api.request({ method: 'post', url: 'auth:test', data: values, }); const data = response?.data?.data; this.setAuthenticator('test'); this.setToken(data?.token); return response; } } const api = new APIClient({ baseURL: 'https://localhost:8000/api', authClass: TestAuth, });子类可以覆写signIn、signUp、signOut等任意方法,并复用基类的setToken、setAuthenticator、setRole等能力。测试断言api.auth是TestAuth的实例,且登录后NOCOBASE_TOKEN与NOCOBASE_AUTH均被正确写入,证明扩展机制完整可用。注意:自定义子类必须调用基类构造函数(或在内部自行注册拦截器),否则请求头自动附加能力将失效。
多应用与 Token 共享
APIClient提供appName与shareToken两个配置项,用于多应用场景:
appName:为当前应用指定存储命名空间,使各应用的 token、角色等互不干扰;shareToken:设为true时,token会统一读写到基础前缀(baseStoragePrefix)之下,实现多个应用共享同一登录态。
相关逻辑位于 Storage.ts 的LocalStorage实现:当shareToken && key === 'token'时,读写使用baseStoragePrefix拼接的 key。测试用例(api-client.test.ts)验证了:两个不同appName的APIClient在shareToken: true时,后一个实例能读到前一个实例写入的 token。
APIClient还支持storageType: 'sessionStorage' | 'memory'来切换存储介质——sessionStorage适合"关闭标签页即退出登录"的场景,memory则完全不落盘,适合测试或敏感环境。
源码级验证:从测试用例看完整链路
NocoBase SDK 的测试目录 提供了对Auth行为的直接验证:
- signIn 全链路(api-client.test.ts):mock
auth:signIn响应后,断言 token 与 authenticator 均已写入内存与 localStorage; - syncCookies 与拦截器(api-client.test.ts):断言请求头为
Bearer 123,确认Authorization自动附加逻辑; - 角色 Cookie(api-client.test.ts):断言角色 Cookie 的写入与清除;
- 存储命名(Storage.test.ts):验证
toUpperCase的 key 拼接规则与localStorage/sessionStorage读写。
在客户端应用中,apiClient.auth.token也被广泛用于判断登录态,例如 client-v2/Application.tsx 与 client-v2/BaseApplication.tsx 都会读取auth.token来初始化带认证的 WebSocket 连接等场景。这说明Auth不仅是 API 调用的认证层,也是整个客户端登录态的数据源。
小结
Auth是 NocoBase 前端 SDK 的认证核心,随APIClient自动实例化,并通过请求拦截器为所有请求附加X-Locale、X-Role、X-Authenticator、Authorization与X-CSRF-Token;- 四个实例属性
locale、role、token、authenticator分别持久化到 localStorage(key 为NOCOBASE_*),其中role额外同步 Cookie,token变更会派发auth:tokenChanged事件; signIn登录成功后自动持久化 token 与认证器,signUp仅注册、signOut完整清理本地登录态,另有syncCookies、lostPassword、resetPassword、checkResetToken等配套方法;- 通过
authClass可扩展自定义认证协议,通过appName/shareToken/storageType可控制多应用隔离、token 共享与存储介质; - 以上全部行为均有 packages/core/sdk/src/Auth.ts、packages/core/sdk/src/APIClient.ts、packages/core/sdk/src/Storage.ts 及 packages/core/sdk/src/tests/api-client.test.ts 等源码与测试背书,可在仓库中进一步查阅。
关于认证器(Authenticator)的概念与配置,可继续阅读 用户认证文档。
【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考