@rootauth/web-components 提供与框架无关的 RootAuth 自定义元素,支持登录、注册、重置密码和 MFA 二次认证。
在 RootAuth 工作台 创建应用,并复制 app_id(格式如 app_******)。

请在项目根目录的 .npmrc 文件中添加下面这行配置:
@rootauth:registry=http://gitlab.standard-software.co/api/v4/projects/12421/packages/npm/
pnpm add @rootauth/web-components
也可以使用 npm:
npm install @rootauth/web-components
初始化函数会注册四类 RootAuth 自定义元素,并接收所有元素共用的全局 config。
import { defineRootAuthWebComponents } from '@rootauth/web-components'
defineRootAuthWebComponents({
config: {
app_id: 'your-app-id',
api_base_url: 'https://rootauth-api.rootauth.com',
redirect_uri: window.location.origin,
scope: ['openid'],
locale: 'zh-CN',
},
})
config 是必填的全局参数,在初始化时统一传入,登录、注册、重置密码和 MFA 组件共用该配置。注册函数是幂等的,重复调用不会重复注册同名元素。
默认注册以下元素:
| 元素 | 用途 |
|---|---|
<rootauth-login> |
登录 |
<rootauth-register> |
注册 |
<rootauth-reset-password> |
重置密码 |
<rootauth-mfa> |
登录后的 MFA 二次认证 |
<rootauth-login type="email-password"></rootauth-login>
const login = document.querySelector('rootauth-login')!
login.addEventListener('success', event => {
console.log('登录成功', event.detail.data, event.detail.values)
})
login.addEventListener('error', event => {
console.error(event.detail.message, event.detail.error)
})
config.app_id 是必填项。未传 config.api_base_url 时使用 https://rootauth-api.rootauth.com。
组件在 HTML 中使用标签挂载。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type |
元素对应的枚举值 | 各组件默认类型 | 选择登录、注册、重置密码或 MFA 页面类型 |
submit-text |
string |
当前语言默认文案 | 覆盖提交按钮文字 |
size |
large | default | small |
default |
同时作为输入控件和按钮的默认尺寸 |
input-size |
large | default | small |
使用 size |
只覆盖输入控件尺寸 |
button-size |
large | default | small |
使用 size |
只覆盖按钮尺寸 |
required-marks |
boolean |
false |
显示全部字段必填星号;只影响显示 |
show-remember-password |
boolean |
false |
仅登录组件使用,显示“记住密码” |
<rootauth-login
type="email-code"
size="large"
input-size="default"
button-size="large"
required-marks
submit-text="Continue"
></rootauth-login>
<rootauth-login
type="email-code"
submit-text="继续"
size="large"
input-size="default"
button-size="large"
required-marks
show-remember-password
></rootauth-login>
FieldKey 可取:email、username、phone、password、newPassword、confirmPassword、code、mfaEmail、mfaPhone、mfaCode、mfaSecondaryCode。
对象和函数参数 fieldLabels、requiredMarks、fieldIcons、fieldPlaceholders、beforeSubmit 通过元素 property 设置,不作为 HTML 标签属性。
无效的 type、size 或 MFA type 会回退到该元素的默认值。无效的全局 config.locale 会回退到 zh-CN。
字段外观通过 fieldIcons 和 fieldPlaceholders 统一配置。fieldIcons 可整体关闭图标,也可通过字段映射控制部分图标;fieldPlaceholders 覆盖输入框以及区号搜索框的 placeholder。
fieldIcons 设为 true 时显示当前内置默认图标,设为 false 时当前元素的所有字段前置图标都不显示。传入对象时,键使用 FieldKey:字段值为 true 时使用默认图标,false 时隐藏该字段图标,图片 URL 则替换该字段图标;未配置字段继续使用内置图标。图片 URL 可以是站内地址、完整 URL、Data URL 或 SVG Data URL。组件将 URL 放入 <img>,不执行任意 HTML。
fieldPlaceholders 支持全部 FieldKey,并额外支持 phoneCodeSearch,用于手机号区号下拉框中的搜索输入框。
<rootauth-login id="styled-login" type="email-password"></rootauth-login>
<script type="module">
const login = document.querySelector('#styled-login')
login.fieldIcons = { email: false, password: '/assets/password-icon.svg' }
login.fieldPlaceholders = { email: '请输入工作邮箱', password: '请输入账户密码' }
</script>
组件为稳定的内部结构声明了标准 part,用户侧可以通过 组件选择器::part(name) 覆盖 Shadow DOM 内的样式,不需要依赖内部 .rootauth-wc-* class。
| Part | 对应内容 |
|---|---|
form |
表单根节点 |
field |
单个字段容器 |
label、required-mark |
字段 label 和必填标记 |
control、control-error、control-disabled |
输入控件及错误、禁用状态 |
input、icon、input-action |
输入框、前置图标和清除/密码可见操作 |
error |
字段错误文案 |
phone-code-trigger |
手机区号下拉触发按钮 |
phone-code-dropdown、phone-code-search、phone-code-option |
区号下拉层、搜索框和选项 |
code-row、code-button |
验证码输入行和发送按钮 |
submit-button、submit-loading |
提交按钮及 loading 状态 |
remember-password、remember-password-checkbox |
记住密码区域和复选框 |
agreement、agreement-error |
注册协议及未确认错误状态 |
totp-container、totp-qrcode、totp-secret |
TOTP 设置区域、二维码和手动密钥 |
rootauth-login::part(control) {
border-radius: 8px;
background: #fff;
}
rootauth-login::part(input) {
font-family: Inter, sans-serif;
}
rootauth-login::part(submit-button) {
border: 0;
border-radius: 8px;
background: #111827;
font-weight: 600;
}
rootauth-login::part(control-error) {
box-shadow: 0 0 0 1px #dc2626 inset;
}
::part() 不支持继续选择 part 内部的后代元素,例如 ::part(control) input 无效;请直接使用 ::part(input)。全局提示消息位于 document light DOM,可通过 .rootauth-wc-global-message-host .rootauth-wc-message 使用普通 CSS 修改。
config 参数config 是 defineRootAuthWebComponents({ config }) 的必填全局初始化参数,类型为 RootAuthElementConfig,并继承 RootAuthClientConfig。初始化后,所有 RootAuth 元素统一使用这份配置,不需要也不应逐个给元素设置 config。完整参数如下:
| 参数 | 类型 | 默认值 | Web Components 中的作用 |
|---|---|---|---|
app_id |
string |
无 | 必填 |
api_base_url |
string |
https://rootauth-api.rootauth.com |
RootAuth API 地址 |
redirect_uri |
string |
window.location.origin |
登录、注册请求的回调地址 |
scope |
string[] |
['openid'] |
OIDC scope |
state |
string |
无 | OIDC state |
grant_type |
string |
authorization_code |
登录、注册请求的授权模式 |
locale |
string |
zh-CN | 多语言设置 |
message |
RootAuthMessageConfig |
{} |
配置全局提示消息 |
show_submit_loading |
boolean |
false |
是否在提交按钮中显示 loading 图标 |
defineRootAuthWebComponents({
config: {
app_id: 'your-app-id',
api_base_url: 'https://api.example',
locale: 'zh-CN',
message: { duration: 5000 },
show_submit_loading: true,
},
})
messageinterface RootAuthMessageConfig {
colors?: Partial<Record<'primary' | 'success' | 'warning' | 'info' | 'error', string>>
duration?: number
show_error?: boolean
}
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
colors |
Partial<Record<MessageType, string>> |
内置颜色 | 覆盖提示消息颜色 |
duration |
number |
5000 |
消息自动关闭毫秒数;<= 0 时不自动关闭,但仍可手动关闭 |
show_error |
boolean |
true |
是否显示默认错误提示;关闭后仍会派发 error |
defineRootAuthWebComponents({
config: { message: { colors: { error: '#f00' }, duration: 3000, show_error: true } },
})
MessageType 为 primary、success、warning、info、error。
<rootauth-login> 根据 type 渲染邮箱、手机号或用户名登录表单,并自动处理验证码、密码加密、字段校验和 MFA 事件。
元素:<rootauth-login>,对应类:RootAuthLoginElement。
type| 值 | 登录方式 | 字段 | API type |
|---|---|---|---|
email-password |
邮箱 + 密码登录 | email、password |
EMAIL_PASS |
phone-password |
手机号 + 密码登录 | phoneCode、phoneNum、password |
PHONE_PASS |
username-password |
用户名 + 密码登录 | username、password |
USER_NAME_PASS |
email-code |
邮箱 + 验证码登录 | email、code |
EMAIL_CODE |
phone-code |
手机号 + 验证码登录 | phoneCode、phoneNum、code |
PHONE_CODE |
默认值为 email-password。验证码登录点击“获取验证码”后会触发 code-sent;手机号区号来自【工作台-登陆控制-手机区号策略】。
<rootauth-login type="email-password" submit-text="登录" show-remember-password></rootauth-login>
showRememberPassword 控制密码登录表单是否显示“记住密码”复选框,默认值为 false。该属性只对 email-password、phone-password 和 username-password 生效,验证码登录不会显示。
<rootauth-login type="email-password" show-remember-password></rootauth-login>
用户勾选后,组件在登录接口成功返回时将当前登录类型、账号和原始密码加密保存到 localStorage;下次挂载相同登录类型时自动回填并保持勾选。用户取消勾选并成功登录后,组件清除已保存记录。登录返回 MFA 要求时,首因子已经验证成功,因此也会执行保存。
<rootauth-register> 根据 type 渲染邮箱、手机号或用户名注册表单。组件根据后端配置处理密码规则、验证码和用户协议。
元素:<rootauth-register>,对应类:RootAuthRegisterElement。
type| 值 | 注册方式 | 字段 | API type |
|---|---|---|---|
email-code-password |
邮箱验证码 + 密码注册 | email、code、password |
EMAIL_CODE_PASS |
phone-code-password |
手机验证码 + 密码注册 | phoneCode、phoneNum、code、password |
PHONE_CODE_PASS |
username-password |
用户名 + 密码注册 | username、password |
USER_NAME_PASS |
默认值为 email-code-password。
<rootauth-register type="email-code-password" submit-text="注册"></rootauth-register>
注册协议是否显示、协议内容以及是否要求用户勾选,取决于【工作台-全局登录-功能配置】中是否开启控制。组件不提供前端隐藏协议的参数;用户未勾选会阻止提交。
<rootauth-reset-password> 支持邮箱或手机号验证码找回密码,并在请求前校验和加密新密码。
元素:<rootauth-reset-password>,对应类:RootAuthResetPasswordElement。
type| 值 | 重置方式 | 字段 | API type |
|---|---|---|---|
email |
邮箱验证码重置 | email、code、password、password_confirmation |
EMAIL_CODE |
phone |
手机验证码重置 | phoneCode、phoneNum、code、password、password_confirmation |
PHONE_CODE |
默认值为 email。新密码和确认密码都会在请求前使用应用配置中的 RSA 公钥加密,并执行密码一致性校验。
<rootauth-reset-password type="email" submit-text="重置密码"></rootauth-reset-password>
<rootauth-mfa> 处理邮箱、手机号和 TOTP 验证,也支持首次绑定验证器,该组件接收登录接口返回的 MFA 数据。
元素:<rootauth-mfa>,对应类:RootAuthMfaElement。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type |
otp | phone | email |
otp |
MFA 页面类型 |
mfaType |
MfaMethod | undefined |
按 type 推断 |
精确指定 API mfa_type |
mfaToken |
string |
'' |
登录接口返回的 mfa_token;提交必需 |
email |
string |
'' |
邮箱;传入后邮箱输入框只读 |
phoneCode |
string |
'' |
手机号区号 |
phoneNum |
string |
'' |
手机号;传入后手机号输入框只读 |
phoneMask |
string |
'' |
展示脱敏手机号;传入后手机号输入框只读 |
phoneAllowCodes |
string[] |
['86'] |
可选手机号区号 |
totpSecret |
string |
'' |
TOTP 密钥或完整 otpauth:// URI;有值时生成二维码 |
totpBindNeedVerifyCode |
boolean |
false |
是否要求 TOTP 绑定前验证邮箱或手机号 |
mfaTotpText |
MfaTotpTextConfig |
{} |
TOTP 设置流程文案 |
totpSetupHint |
string |
'' |
二维码设置提示 |
totpManualEntryHint |
string |
'' |
手动输入密钥提示 |
totpScanProblemText |
string |
'' |
“无法扫码”操作文案 |
totpScanQrCodeText |
string |
'' |
“显示二维码”操作文案 |
mfaCodePlaceholder |
string |
'' |
MFA 验证码输入框 placeholder |
<rootauth-mfa
type="otp"
mfa-type="TOTP_BIND"
mfa-token="mfa_token_value"
email="user@example.com"
phone-code="86"
phone-num="13800138000"
phone-mask="138****8000"
phone-allow-codes="86,852"
totp-secret="JBSWY3DPEHPK3PXP"
totp-bind-need-verify-code
totp-setup-hint="扫描二维码"
totp-manual-entry-hint="手动输入密钥"
totp-scan-problem-text="无法扫码"
totp-scan-qr-code-text="显示二维码"
mfa-code-placeholder="请输入验证码"
></rootauth-mfa>
<rootauth-mfa
type="otp"
mfa-totp-text='{"setup_hint":"请使用验证器扫描二维码","manual_entry_hint":"无法扫码时,请手动输入密钥","scan_problem":"无法扫描二维码","scan_qr_code":"返回二维码"}'
></rootauth-mfa>
mfaType 完整列表mfaType |
验证方式 | code 内容 |
额外参数 |
|---|---|---|---|
EMAIL |
已绑定邮箱验证 | 邮箱验证码 | email 可由登录响应传入 |
EMAIL_BIND |
绑定邮箱并验证 | 邮箱验证码 | email |
PHONE_CODE |
已绑定手机号验证 | 短信验证码 | phoneCode、phoneNum 或 phoneMask |
PHONE_CODE_BIND |
绑定手机号并验证 | 短信验证码 | phoneCode、phoneNum |
TOTP |
已绑定验证器验证 | 验证器动态码 | 无 |
TOTP_BIND |
首次绑定验证器 | 验证器动态码 | totpSecret;选择验证码时还需要绑定验证码 |
<rootauth-mfa type="otp" mfa-type="TOTP_BIND"></rootauth-mfa>
mfaType 未传时的推断规则:type="phone" -> PHONE_CODE,type="email" -> EMAIL,type="otp" -> TOTP。
当 type="otp" 且 totpBindNeedVerifyCode=true 时,组件根据已绑定项显示邮箱或手机号验证码;仅绑定一项时直接使用该项,同时绑定两项时按登录方式选择初始渠道。该值为 false 时不显示也不提交 totp_bind_code。
loginAccountType 和 totpAccountName 由登录组件根据登录方式自动生成,并通过 mfa_token 传递给 MFA 组件,业务方无需设置。
从登录接口获取 MFA 数据后,可以这样挂载:
<rootauth-mfa
type="email"
mfa-token="mfa_token_value"
email="user@example.com"
></rootauth-mfa>
TOTP 绑定示例:
<rootauth-mfa type="otp" mfa-token="mfa_token_value"></rootauth-mfa>
仅当 type="otp"、totpBindNeedVerifyCode=true,且登录 MFA 响应同时返回 email 和手机号(phone_num 或 phone_num_mask)时,OTP 绑定验证账号行才显示切换按钮。只绑定一项时直接使用该项,不显示切换按钮;切换到独立 email 或 phone MFA 页面后也不显示该按钮。
登录响应中的 MFA 参数可以直接映射到标签属性:
<rootauth-mfa
type="otp"
mfa-type="TOTP_BIND"
mfa-token="mfa_token_value"
email="user@example.com"
phone-code="86"
phone-num="13800138000"
phone-mask="138****8000"
totp-secret="JBSWY3DPEHPK3PXP"
totp-bind-need-verify-code
></rootauth-mfa>
公开方法允许业务方在不操作 Shadow DOM 的情况下写入表单状态。当前提供 setValues(),可用于回填账号、区号或其他字段。
setValues(values)setValues(values: Record<string, string | number | boolean | null | undefined>): void
批量设置字段值并重新渲染。null 和 undefined 会被忽略,其他值会转换为字符串,并触发一次 value-change。
login.setValues({
email: 'user@example.com',
password: 'Password1',
})
常用字段名:
| 元素 | 字段名 |
|---|---|
| 登录 | email、phoneCode、phoneNum、username、password、code |
| 注册 | email、phoneCode、phoneNum、username、password、code |
| 重置密码 | email、phoneCode、phoneNum、password、password_confirmation、code |
| MFA | email、phoneCode、phoneNum、code、bindCode |
组件通过 DOM CustomEvent 向外部传递成功、错误、验证码发送、字段变化、MFA 要求和密钥复制状态。
所有自定义事件都设置了 bubbles: true 和 composed: true,可以在组件本身或祖先节点监听。
success登录、注册、重置密码或 MFA 成功时触发。
interface RootAuthSuccessDetail {
source: 'login' | 'register' | 'reset-password' | 'mfa'
data?:
| CustomerLoginResponse
| RegisterWithCaptchaResponse
| LoginSuccessData
| Record<string, never>
values: Record<string, string>
}
error请求失败、验证码失败或配置错误时触发。
interface RootAuthErrorDetail {
source: 'login' | 'register' | 'reset-password' | 'mfa'
error: unknown
message: string
}
code-sent邮箱、手机或 MFA 验证码发送成功时触发。发送成功后按钮按应用配置 verify_code_resend_interval_seconds 进入倒计时;配置缺失或无效时使用 60 秒。
获取验证码时,如果出现“验证码错误次数过多,请重新获取”的错误提示,请到【工作台-通用安全-验证码规则-验证码尝试次数】查看次数是否符合需求。
interface RootAuthCodeSentDetail {
source: 'login' | 'register' | 'reset-password' | 'mfa'
target: 'email' | 'phone'
values: Record<string, string>
}
value-change字段输入、清空、手机号区号选择或 setValues 后触发。
interface RootAuthValueChangeDetail {
source: 'login' | 'register' | 'reset-password' | 'mfa'
values: Record<string, string>
}
mfa-required登录成功但后端要求 MFA 时由登录组件触发。此时不会触发 success。
interface RootAuthMfaRequiredDetail {
data: CustomerLoginResponse
loginAccountType: 'EMAIL' | 'PHONE' | 'USERNAME'
values: Record<string, string>
}
data 通常包含 mfa_token、mfa_methods、email、email_mask、phone_code、phone_num、phone_num_mask 和 totp_secret。loginAccountType 是登录组件根据当前 type 明确给出的登录账号类型。
totp-secret-copied用户在 TOTP 手动输入模式点击复制密钥并复制成功后触发。
interface RootAuthTotpSecretCopiedDetail {
source: 'mfa'
secret: string
}
插槽允许在账号输入区和提交按钮前后加入业务内容,同时保留组件自身的布局和请求逻辑。
使用时将业务元素写在 RootAuth 标签内部,并通过 slot="插槽名" 指定位置;无需访问 Shadow DOM,也无需使用 JavaScript 创建节点。
当前支持以下命名插槽:
| slot | 出现位置 | 适用元素 |
|---|---|---|
before-submit |
提交按钮之前 | 登录、注册 |
after-submit |
提交按钮之后 | 登录、注册、重置密码 |
account-suffix |
账号控件右侧 | 验证码登录、重置密码、TOTP 邮箱/手机号验证 |
before-submit 适合放置忘记密码、辅助操作等内容。after-submit 适合放置协议、注册入口或流程说明。account-suffix 与账号输入框位于同一行;组件自身需要显示 MFA 验证方式切换时,会优先使用内置切换按钮。<rootauth-login type="email-code">
<button slot="account-suffix" type="button">切换账号类型</button>
<a slot="before-submit" href="/help">无法登录?</a>
</rootauth-login>
<rootauth-mfa type="otp" totp-bind-need-verify-code>
<button slot="account-suffix" type="button">切换验证方式</button>
</rootauth-mfa>
未声明对应命名插槽的组件会忽略该位置;插槽内容的点击、链接跳转和业务状态仍由接入页面自行处理。
组件会读取后端应用配置来决定验证码、密码规则、手机号区号和用户协议,并统一派发成功或错误事件。
success 和 error 都是可取消事件;监听器调用 event.preventDefault() 可覆盖默认跳转或默认错误提示。document.body 顶部,组件切换或卸载后仍显示到自动关闭;可通过 message.show_error: false 全局关闭默认错误提示。style.css。包入口导出初始化配置、组件属性、字段映射、事件详情和各流程枚举类型。
import type {
RootAuthElementConfig,
RootAuthFieldIcon,
RootAuthFieldIcons,
RootAuthFieldLabels,
RootAuthFieldPlaceholders,
RootAuthPlaceholderKey,
RootAuthLoginType,
RootAuthLoginElementProps,
RootAuthRegisterType,
RootAuthResetPasswordType,
RootAuthMfaType,
RootAuthMfaElementProps,
RootAuthRegisterElementProps,
RootAuthSuccessDetail,
RootAuthErrorDetail,
RootAuthCodeSentDetail,
RootAuthMfaRequiredDetail,
RootAuthValueChangeDetail,
} from '@rootauth/web-components'
完整示例组合全局 API 配置、组件尺寸、label、图标、placeholder、提交前钩子和组件事件监听,可作为业务接入模板。
<rootauth-login id="rootauth-login" type="email-password"></rootauth-login>
<rootauth-mfa type="otp" mfa-token="mfa_token_value"></rootauth-mfa>
import { defineRootAuthWebComponents, type RootAuthElementConfig } from '@rootauth/web-components'
const config: RootAuthElementConfig = {
app_id: 'your-app-id',
api_base_url: 'https://rootauth-api.rootauth.com',
redirect_uri: window.location.origin,
scope: ['openid'],
state: 'your-state',
locale: 'zh-CN',
message: {
duration: 5000,
colors: {
success: '#16a34a',
error: '#dc2626',
},
},
show_submit_loading: false,
}
defineRootAuthWebComponents({ config })
const login = document.querySelector('rootauth-login')!
login.requiredMarks = true
login.showRememberPassword = true
login.fieldLabels = { email: '工作邮箱', password: '账户密码' }
login.fieldIcons = { email: false, password: '/assets/password-icon.svg' }
login.fieldPlaceholders = { email: '请输入工作邮箱' }
login.beforeSubmit = async () => {
// 返回 false 可取消本次提交
return true
}
login.addEventListener('success', event => {
console.log('流程成功', event.detail)
})
login.addEventListener('error', event => {
console.error('流程失败', event.detail.message)
})
@rootauth/core:无 UI API@rootauth/vue:Vue 3 hosted 完整认证页面@rootauth/react:React 18+ hosted 完整认证页面