资讯动态

NocoBase 扩展认证类型实战:从 Auth/BaseAuth 内核机制到客户端 registerType 注册全链路

发布时间:2026/9/14 10:41:08 来源:尧图企业网站定制
NocoBase 扩展认证类型实战从 Auth/BaseAuth 内核机制到客户端 registerType 注册全链路【免费下载链接】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本篇围绕 NocoBase「扩展认证类型」的完整开发流程展开覆盖两类认证不依赖第三方回调、依赖第三方回调的标准时序以及如何继承内核Auth/BaseAuth抽象类、复用 JWT 鉴权逻辑、借助AuthModel处理用户数据、通过AuthManager.registerTypes注册服务端类型与客户端registerType注册 UI 组件。读完你将能够独立完成一个自定义登录插件如短信、OIDC、SAML并理解 NocoBase 认证中间件、X-Authenticator头、users/authenticators/usersAuthenticators三表协作的底层实现。认证模型两种类型的标准时序NocoBase 支持按需要扩展用户认证类型。从实现角度看认证一般分为两类不依赖第三方回调在 NocoBase 应用内完成身份判断如密码登录、短信登录。依赖第三方回调由第三方服务判断用户身份并将结果通过回调通知 NocoBase如 OIDC、SAML。两者在 NocoBase 中的认证流程基本如下。不依赖第三方回调客户端使用 NocoBase SDK 调用登录接口api.auth.signIn()请求登录接口auth:signIn同时把当前使用的认证器标识通过请求头X-Authenticator携带给后端。该请求头的键名由内核在服务端启动时注入——从源码结构看application.ts 中将authKey: X-Authenticator写入AuthManager选项。auth:signIn接口根据请求头中的认证器标识转发到认证器对应的认证类型由该认证类型注册的认证类中的validate方法进行相应的逻辑处理。客户端从auth:signIn接口响应中拿到用户信息和认证token将token保存到 Local Storage完成登录。这一步由 SDK 内部自动完成处理。auth:signIn等接口本身就是内核注册的标准资源操作定义在 actions.ts 中signIn先做来源校验再调用ctx.auth.signIn()signOut调用ctx.auth.signOut()并派发auth:signOut事件check则直接返回当前用户并对users集合中标记hidden的字段做过滤。依赖第三方回调客户端通过自己注册的接口比如auth:getAuthUrl获取第三方登录 URL并按协议携带应用名称、认证器标识等信息。跳转到第三方 URL 完成登录第三方服务调用 NocoBase 应用的回调接口需要自己注册比如auth:redirect返回认证结果同时返回应用名称、认证器标识等信息。回调接口方法解析参数获得认证器标识通过AuthManager获取对应的认证类主动调用auth.signIn()方法。auth.signIn()会调用validate()方法处理鉴权逻辑。回调方法拿到认证token再 302 跳转回前端页面并在 URL 参数带上token和认证器标识?authenticatorxxxtokenyyy。下面介绍如何注册服务端接口和客户端用户界面。服务端认证接口NocoBase 内核提供了扩展认证类型的注册和管理。扩展登录插件的核心逻辑处理需要继承内核的Auth抽象类并对相应的标准接口进行实现。完整 API 参考 Auth。Auth抽象类定义在 auth.ts 中其抽象方法与构造配置为import { Auth } from nocobase/auth; class CustomAuth extends Auth { set user(user) {} get user() {} async check() {} async signIn() {} }从源码结构看Auth构造入参类型为AuthConfig { authenticator: Authenticator; options: Recordstring, any; ctx: Context }即认证实例在创建时已经绑定了具体的认证器authenticator与请求上下文ctx因此认证类内部可以直接访问认证器配置与ctx.db。除文档列出的check/signIn外内核还约定了checkToken()、signUp()、signOut()、syncCookies()等接口并定义了统一错误码AuthErrorCode如EMPTY_TOKEN、EXPIRED_TOKEN、INVALID_TOKEN、NOT_EXIST_USER等便于各认证类型抛出语义化错误。内核也注册了用户认证相关的基本资源操作。API说明auth:check判断用户是否登录auth:signIn登录auth:signUp注册auth:signOut注销登录多数情况下扩展的用户认证类型也可以沿用现有的 JWT 鉴权逻辑来生成用户访问 API 的凭证。内核的BaseAuth类对Auth抽象类做了基础实现参考 BaseAuth。插件可以直接继承BaseAuth类以便复用部分逻辑代码降低开发成本。import { BaseAuth } from nocobase/auth; class CustomAuth extends BaseAuth { constructor(config: AuthConfig) { // 设置用户数据表 const userCollection config.ctx.db.getCollection(users); super({ ...config, userCollection }); } // 实现用户认证逻辑 async validate() {} }BaseAuth 的 JWT 复用逻辑BaseAuth定义在 base/auth.ts。从源码结构看它把「认证validate」与「发证sign token」解耦构造时必须传入userCollection用于userRepository查询用户。validate()默认返回null由子类覆写完成真正的身份核验并返回Model用户。signIn()是完整登录链先调用validate()得到用户若失败抛出 401NOT_EXIST_USER随后调用signNewToken(user.id)生成 JWT再setAuthCookies/setSessionCookies写入浏览器 Cookie最终返回{ user, token }。check()/checkToken()负责校验请求携带的 JWT解码、按jti查询黑名单、比对signInTime/iat判断是否过期并在 token 过期但未超限时通过tokenController.renew(jti)完成无感续期把新 token 写入x-new-token响应头与 Cookie。signOut()会清空认证 Cookie、删除用户角色与用户缓存并将当前 token 加入黑名单jwt.block。这套逻辑由AuthManager注入的jwtJwtService与tokenController驱动意味着子类只需关注「如何核验身份」发凭证、会话续期、登出失效全部由基类兜底。认证中间件与 X-Authenticator 解析请求如何路由到具体认证类核心在 auth-manager.ts 的middleware()从请求头读取authKey即X-Authenticator得到headerAuthenticator若没有则回退到 Cookie 中的authenticator再回退到默认认证器。通过authManager.get(name, ctx)依据认证器名创建对应认证实例并挂载到ctx.auth。调用ctx.auth.skipCheck()判断是否可以跳过鉴权如公开接口、optionalAuth、关闭 ACL 等否则调用ctx.auth.check()校验用户并写入ctx.auth.user。AuthManager.get()会先查内置认证器registerBuiltInAuthenticator注册未命中则通过storer从authenticators集合加载最终调用createAuth依据authType取出对应认证类构造函数并new出实例——找不到类型时会抛出AuthType [xxx] is not found.。服务端用户数据在实现用户认证逻辑时通常涉及用户数据处理。在 NocoBase 应用中默认情况下相关的表定义为数据表作用插件users存储用户信息邮箱、昵称和密码等用户插件 (nocobase/plugin-users)authenticators存储认证器认证类型实体信息对应认证类型和配置用户认证插件 (nocobase/plugin-auth)usersAuthenticators关联用户和认证器保存用户在对应认证器下的信息用户认证插件 (nocobase/plugin-auth)这三张集合的定义分别位于nocobase/plugin-authauthenticators.ts 与 users-authenticators.ts。从源码结构看authenticators集合以name为唯一键unique: true并携带authType、title、description、JSON 类型的options、布尔enabled其users为belongsToMany关联through: usersAuthenticatorssourceKey: name、targetKey: id。usersAuthenticators集合显式定义了uuid必填该认证方式下的用户唯一标识、nickname、avatar、JSON 类型的metauserId/authenticator两个关联键由上述belongsToMany隐式生成。通常情况下扩展登录方式用users和usersAuthenticators来存储相应的用户数据即可特殊情况下才需要自己新增 Collection。usersAuthenticators的主要字段为字段说明uuid该种认证方式的用户唯一标识如手机号、微信 openid 等metaJSON 字段其他需要保存的信息userId用户 IDauthenticator认证器名字唯一标识对于用户查询和创建操作authenticators的数据模型AuthModel也封装了几个方法可以在CustomAuth类中通过this.authenticator[方法名]使用。完整 API 参考 AuthModel。import { AuthModel } from nocobase/plugin-auth; class CustomAuth extends BaseAuth { async validate() { // ... const authenticator this.authenticator as AuthModel; this.authenticator.findUser(); // 查询用户 this.authenticator.newUser(); // 创建新用户 this.authenticator.findOrCreateUser(); // 查询或创建新用户 // ... } }AuthModel的实现见 authenticator.tsfindUser(uuid)通过getUsers关联按uuid命中返回第一个用户。newUser(uuid, userValues?)在事务内createUser默认nickname uuid并在同一事务中建立through: { uuid }的usersAuthenticators关联随后派发users.afterCreateWithAssociations事件。findOrCreateUser(uuid, userValues?)先findUser未命中则newUser。这保证了「按第三方唯一标识查找/创建用户」这一扩展认证最常见操作是原子且一致的。服务端认证类型注册扩展的认证方式需要向认证管理模块注册。class CustomAuthPlugin extends Plugin { async load() { this.app.authManager.registerTypes(custom-auth-type, { auth: CustomAuth, }); } }AuthManager.registerTypes(authType, authConfig)见 auth-manager.ts。从源码结构看authConfig的完整结构为type AuthConfig { auth: AuthExtendAuth; // 认证类 title?: string; // 认证类型展示名会出现在后台认证器类型列表 hidden?: boolean; // 是否在认证器类型列表中隐藏 getPublicOptions?: (options) Recordstring, any; // 计算可公开下发的配置 };即除必选的auth外还可提供title/hidden/getPublicOptions。注册后即可通过listTypes()在后台认证器列表中展示。认证器实例的创建createAuth会依据authType取回auth构造函数并把authenticator.options作为构造入参之一因此后台配置的options会透传给认证类。客户端UI 组件注册客户端用户界面通过用户认证插件客户端提供的接口registerType进行注册import AuthPlugin from nocobase/plugin-auth/client; class CustomAuthPlugin extends Plugin { async load() { const auth this.app.pm.get(AuthPlugin); auth.registerType(custom-auth-type, { components: { SignInForm, // 登录表单 SignInButton, // 登录第三方按钮可以和登录表单二选一 SignUpForm, // 注册表单 AdminSettingsForm, // 后台管理表单 }, }); } }PluginAuthClient.registerType与AuthOptions定义见 index.tsx。从源码结构看AuthOptions.components的每个组件都会接收一个authenticator属性SignUpForm接收authenticatorName便于组件读取当前认证器上下文export type AuthOptions { components: Partial{ SignInForm: ComponentType{ authenticator: AuthenticatorType }; SignInButton: ComponentType{ authenticator: AuthenticatorType }; SignUpForm: ComponentType{ authenticatorName: string }; AdminSettingsForm: ComponentType; }; };内核自身的预设认证类型也是通过同一接口注册的——PluginAuthClient.load()内registerType(presetAuthType, { components: { SignInForm, SignUpForm, AdminSettingsForm: Options } })说明「注册类型 渲染表单」是统一机制。登录表单如果有多个认证器对应的认证类型都注册了登录表单会以 Tab 的形式展示。Tab 标题为后台配置的认证器标题。登录按钮通常为第三方登录按钮实际上可以是任意组件。注册表单如果需要从登录页跳转到注册页需要在登录组件中自己处理。后台管理表单上方为通用的认证器配置下方为可注册的自定义配置表单部分。请求接口在客户端发起用户认证相关的接口请求可以使用 NocoBase 提供的 SDK。import { useAPIClient } from nocobase/client; // use in component const api useAPIClient(); api.auth.signIn(data, authenticator);详细 API 参考 nocobase/sdk - Auth。端到端小结把上述各部分串起来一个自定义认证类型的完整落地路径是服务端继承继承BaseAuth或Auth覆写validate()完成身份核验返回Model用户登录、发凭证、会话续期、登出失效由基类兜底。用户数据默认复用usersusersAuthenticators用AuthModel.findUser / newUser / findOrCreateUser完成「第三方唯一标识 → NocoBase 用户」的映射。类型注册在插件load()中调用authManager.registerTypes(custom-auth-type, { auth: CustomAuth })必要时提供title/hidden/getPublicOptions。客户端注册通过auth.registerType(custom-auth-type, { components: { SignInForm / SignInButton / SignUpForm / AdminSettingsForm } })注册 UI。请求链路客户端api.auth.signIn(data, authenticator)→ 请求头X-Authenticator标识认证器 →AuthManager.middleware()解析并创建认证实例 →signIn()调用validate()→ 返回{ user, token }token 进入后续 API 鉴权。依赖第三方回调的类型额外增加「获取第三方登录 URL 注册回调接口 回调内主动调用auth.signIn() 302 带回 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价