@fatal_blow/auth-ui
v0.4.1
Published
云枢统一认证 UI 组件库 — 登录/注册/找回密码/改密码,对接自研 auth_backend,可复用于多个项目
Maintainers
Readme
@fatal_blow/auth-ui
云枢统一认证 UI 组件库 — 登录 / 注册 / 找回密码 / 改密码,对接自研 auth_backend,可复用于多个项目
定位
云枢智能工作室旗下多个项目(Trade Client、其他桌面/Web 应用)共用本组件库实现认证 UI。
后端为自研统一认证服务 auth_backend(Go + PostgreSQL + Redis,部署在腾讯云),不使用 Casdoor。
每个项目自行配置 API 地址、租户 ID、主题、token 存储方式,按需引入认证功能。
三层架构
src/
├── core/ ← 层 1:纯 TS,零 DOM 依赖,跨端复用
│ ├── AuthApiClient.ts fetch + 超时 + X-Tenant-Id + Bearer + 统一错误码
│ ├── types.ts AuthConfig / TokenSet / User / LoginResult ...
│ ├── errors.ts ApiError + 错误码归一化 + 默认文案
│ ├── storage.ts TokenStorage 接口 + Memory/LocalStorage 实现
│ └── index.ts core 入口(@fatal_blow/auth-ui/core)
├── react/ ← 层 2 + 层 3:React DOM
│ ├── provider/ AuthUIProvider(注入 config/storage/theme/navigation + 共享认证状态)
│ ├── hooks/ useAuth + Headless Hooks(useLoginForm / useRegisterForm / ...)
│ ├── theme/ 设计系统 token(色阶/圆角/字号)+ CSS 变量注入
│ ├── components/ AuthLayout / AuthInput / AuthButton / AuthLink / AuthAlert / AuthCheckbox
│ ├── modules/ login / register / forgot-password / change-password
│ └── styles/ base.css(组件库基础样式,className 体系)
└── index.ts ← 主入口(统一导出)三档定制深度
| 档位 | 定制能力 | 用法 |
|------|---------|------|
| L1 | 主题覆盖(颜色、字体、圆角) | <AuthUIProvider mode="dark" theme={...}> |
| L2 | 组件组合 + Headless Hook | useLoginForm() + 原子组件 + AuthLayout 组装 |
| L3 | 完全自定义 UI | 只用 AuthApiClient + useAuth(),UI 全自己写 |
L1:省心 — 直接用页面组件
import { AuthUIProvider, LoginPage, LocalStorageTokenStorage } from '@fatal_blow/auth-ui';
const config = { baseUrl: 'https://admin.voicelnk.cn/api/v1', tenantId: 'voicelnk' };
<AuthUIProvider config={config} storage={new LocalStorageTokenStorage('my-app')} mode="dark">
<LoginPage
logo={<img src="/logo.png" />}
extraFields={<label><input type="checkbox" /> 记住我</label>}
/>
</AuthUIProvider>L2:灵活 — Headless Hook + 原子组件
import { useLoginForm, AuthLayout, AuthInput, AuthButton, AuthAlert } from '@fatal_blow/auth-ui';
function MyLoginPage() {
const form = useLoginForm();
return (
<AuthLayout title="登录" logo={<MyLogo />}>
<form onSubmit={e => { e.preventDefault(); form.submit(); }} className="authui-form">
<AuthInput label="邮箱" type="email" value={form.email} onChange={e => form.setEmail(e.target.value)} />
<AuthInput label="密码" type="password" value={form.password} onChange={e => form.setPassword(e.target.value)} />
{form.error && <AuthAlert variant="error">{form.error}</AuthAlert>}
<AuthButton loading={form.loading}>登录</AuthButton>
</form>
</AuthLayout>
);
}L3:完全控制 — 只用 Core API
import { AuthApiClient, MemoryTokenStorage } from '@fatal_blow/auth-ui/core';
const client = new AuthApiClient({ baseUrl: '...', tenantId: '...' }, new MemoryTokenStorage());
const result = await client.login({ email, password });
// UI 全自己写核心能力
| 功能 | 页面组件 | Headless Hook | 后端接口 |
|------|---------|--------------|---------|
| 登录 | LoginPage | useLoginForm + useMFAForm | POST /auth/login(含 CAPTCHA / MFA) |
| 注册 | RegisterPage | useRegisterForm | POST /auth/register |
| 找回密码 | ForgotPasswordPage | useForgotPasswordForm | POST /auth/forgot-password + /auth/reset-password |
| 改密码 | ChangePasswordForm | useChangePasswordForm | PUT /user/password |
主题系统
设计系统命名(--authui-color-primary-500 / --authui-radius-md / --authui-font-size-base),支持色阶。
// 方式 1:mode 切换深色/浅色
<AuthUIProvider mode="dark"> // 或 mode="light"
// 方式 2:覆盖主色 + 自定义品牌色
<AuthUIProvider
mode="dark"
theme={{
colors: {
primary: { 500: '#ff6b6b', 600: '#e05555', 700: '#cc4444' },
'brand-green': { 500: '#22c55e', 600: '#16a34a', 700: '#15803d' },
}
}}
>
// 方式 3:纯 CSS 覆盖(无需 JS)
// .authui-root { --authui-color-primary-500: #ff6b6b; }内置主题:defaultTheme / darkTheme / lightTheme,工厂函数:createAuthTheme / createLightTheme / createDarkTheme。
配置外部化
AuthConfig 与 TokenStorage 均由消费方注入,组件库不硬编码任何地址、租户、密钥:
// Web 默认用 localStorage
const storage = new LocalStorageTokenStorage('trade_client');
// Tauri / Electron 自行实现 TokenStorage 接口
// class TauriSecureStorage implements TokenStorage { ... }路由无关
组件库不依赖 react-router-dom。页面跳转通过 navigation 回调交给消费方实现,
适配 react-router / Tauri / Electron 等不同环境。
Demo
cd demo
cp .env.example .env.local # 配置后端地址
npm install
npm run dev环境变量:
# 真实后端
VITE_API_BASE_URL=https://admin.voicelnk.cn/api/v1
VITE_TENANT_ID=voicelnk
VITE_USE_MOCK=false
# Mock 模式(开发,不连真实后端)
VITE_API_BASE_URL=/api/v1
VITE_TENANT_ID=demo
VITE_USE_MOCK=true真实后端测试
已验证 11 个场景全部通过(详见 docs/测试/真实后端端到端测试.md):
- 登录(正确密码 / 错误密码)
- 拉取 /user/profile(Bearer 鉴权)
- 修改密码(含密码历史冲突错误码映射)
- 登出 + 重新登录
- 注册新账号 + 登录
- 找回密码(发验证码 + 重置 + 新密码登录)
- Refresh token 正常刷新(旋转,返回全新 token 对)
- Refresh token 重用检测(旧 token 刷新后立即失效,再次使用返回 401)
测试账号密码说明:测试过程中密码多次变更,受后端密码历史策略限制(保留最近 5 次,不允许改回),当前测试账号
[email protected]密码为E2eTest@2026new。
集成方式
当前阶段用 Git 子模块:
git submodule add https://github.com/yunshu/auth_ui.git external/auth_ui// vite.config.ts
resolve: { alias: { '@fatal_blow/auth-ui': path.resolve(__dirname, 'external/auth_ui/src') } }稳定后切换为 npm 包(私有 registry 或 GitHub Packages)。
技术栈
- React 18+ / TypeScript
- 主题:CSS Variables(设计系统命名,色阶支持)
- 构建工具:Vite
- 后端:auth_backend(Go,腾讯云 admin.voicelnk.cn)
License
Apache-2.0
