登录与账户安全
完成注册、邮箱验证、密码恢复、TOTP 与 SSO 登录并配置登录保护
Clouisle 的认证流程由站点设置决定:密码、邮箱验证、管理员审批、人机验证、强制改密、TOTP 与 SSO 可能同时生效。本页按使用顺序说明每个环节的默认值、失败结果与恢复路径;站点级开关的完整清单见站点设置参考。
注册与邮箱验证
自助注册
-
前往登录页
https://your-domain.com,点击注册。 -
填写注册表单:
字段 约束 用户名 必填、全局唯一、最多 50字符邮箱 必填、全局唯一、需为合法邮箱地址 密码 按站点密码策略校验(默认至少 8位,见密码要求)确认密码 与密码一致 -
若开启人机验证,点击点击验证您是真人完成验证。
-
若开启「注册需同意条款」,勾选用户协议与隐私政策。
-
点击注册提交。
提交后的结果取决于站点设置:
| 站点设置 | 默认值 | 提交后行为 |
|---|---|---|
allow_registration | true | 关闭后注册入口返回 5000(registration_disabled) |
require_approval | true | 开启时账户为待审批(approval_status=pending、is_active=false),管理员收到全局通知;审批前无法登录 |
email_verification | true | 开启时须先验证邮箱才能登录 |
enable_captcha | false | 开启时注册页显示点击式人机验证 |
require_terms_acceptance_on_register | false | 开启时必须勾选条款 |
force_password_change_first_login | false | 开启时新用户首次登录被要求立即改密 |
站点中第一个注册的用户会绕过全部限制:直接激活、邮箱标记为已验证,并被赋予 Super Admin 角色。因此请先完成首个管理员的注册,再开放注册。

邮箱验证
- 验证邮件由 SMTP 发送,未配置 SMTP(
smtp_enabled=false)时发送会失败并返回5007(smtp_not_configured)。 - 邮件包含 6 位验证码和验证链接,有效期 10 分钟(Redis 中
600秒)。 - 重新发送的冷却时间为 60 秒(同一邮箱 + 用途),冷却未到返回
5008并带remaining_seconds。 - 验证码错误返回
5005,链接/验证码过期返回5006。 - 未验证邮箱登录会返回
5004,登录页会直接切到验证步骤并自动重发一封验证码。
登录方式
密码登录
- 前往登录页,输入用户名或邮箱(含
@时按邮箱匹配,邮箱大小写不敏感;不含@时按用户名精确匹配)。 - 输入密码。
- 若开启人机验证,点击点击验证您是真人。
- 点击登录。
登录请求依次通过这些关卡,任何一步失败都会中断后续流程:
- SSO-only 模式:
sso_enabled=true且sso_allow_password_login=false时,密码登录返回6306(password_login_disabled)。 - 人机验证(开启时)。
- 账户存在性:账号不存在与密码错误返回同一个
2003(incorrect_email_or_password),不泄露账号是否存在。 - 锁定状态:仍在锁定期返回
5300(account_locked),并带remaining_seconds。 - 本地密码存在性:SSO 自动创建、没有本地密码的账户无法密码登录,同样返回
2003。 - 密码校验:失败时返回
2003并带remaining_attempts;达到阈值转为锁定(见账户锁定)。 - 账户状态:被停用返回
2004(inactive_user),待审批返回2004(pending_approval_user)。 - TOTP:已绑定 TOTP 时返回
requires_totp=true与 5 分钟有效的临时令牌,进入第二步验证。 - 管理员强制 TOTP:站点设置
require_totp=true且用户未绑定 TOTP 时,返回requires_totp_setup=true与 30 分钟有效的临时令牌,前端跳转/totp-setup完成绑定。 - 邮箱验证(开启时;超级管理员豁免该检查)。
- 密码过期/强制改密:需要改密时响应仍返回令牌,但带
force_password_change=true与reason(expired表示已过期,force表示被要求),前端跳转/change-password?reason=...。
登录成功后,失败计数与锁定状态会被清零,并刷新 last_login。
SSO 单点登录
若组织配置了 SSO,可使用企业凭据登录。
- 前往登录页,点击 SSO 提供商按钮(按钮文案取自提供商的
button_text,如「使用 Google 继续」)。 - 在身份提供商处完成认证。
- 自动跳转回 Clouisle 并登录。
首次 SSO 登录:
- 邮箱匹配开启(
sso_match_by_email,默认开启)且邮箱已存在时,SSO 连接会关联到该账户。 - 否则在允许自动创建时新建账户。新账户没有本地密码、邮箱视为已验证,并按配置进入待审批状态。
支持 OAuth2/OIDC、SAML 2.0 与 CAS。配置与排查详见 SSO 配置。
关闭 sso_allow_password_login 会把站点切换成 SSO-only。切换前请确认至少一个超级管理员已完成 SSO 绑定,否则可能无人能登录后台。
首次登录
首次成功登录后:
- 欢迎界面:显示欢迎消息。
- 资料设置:完善个人资料(可选)。
- 团队分配:可能被加入默认团队(
default_team_id,角色为default_team_role,默认member)。 - 仪表板访问:普通用户进入平台界面,管理员还会看到管理入口。
登录保护
人机验证
开关为 enable_captcha(默认关闭),作用于登录与注册两个表单。它验证的是一次真实的点击+指针轨迹,而不是输入文字。
- 挑战与凭证在 Redis 中保存 300 秒(5 分钟),且一次性使用。
- 校验失败返回
5303(captcha_invalid),缺少凭证返回5302(captcha_required);前端在失败后会自动重新拉取一个新挑战。 - 登录页只在填写了用户名与密码后才加载验证码,因此打开页面时看不到它是正常的。
账户锁定
失败计数是按账户保存在用户记录上的(failed_login_attempts + locked_until),没有滚动时间窗:
max_login_attempts默认5:累计到 5 次立即锁定。lockout_duration_minutes默认15:锁定期间即使密码正确也会被拒(5300)。- 未达阈值时,错误响应会带
remaining_attempts,可据此提示剩余次数。 - 计数不会随时间自动清零:要么登录成功,要么锁定到期后的下一次登录尝试(此时才归零)。
- 触发锁定时会向用户发送
security.account_locked高优先级通知,内容含锁定分钟数。
按 IP 的失败计数(Redis 键 login:attempts:ip:<ip>,TTL 3600 秒)在代码中只有写入/读取函数,没有任何调用方,因此当前版本并未按 IP 限速。锁定只发生在账户维度。
登录异常检测
系统在 Redis 中记录每个账户最近登录过的 IP 与 User-Agent(各最多 10 条,保留 30 天):
- 出现过历史记录后,从新 IP 或新设备登录会触发
security.login_anomaly高优先级通知,内容包含 IP、时间与 User-Agent。 - 首次登录(还没有历史记录)不会告警,避免每次新账号都误报。
- Redis 不可用时该检测会被跳过,登录流程不受影响。
密码管理
密码要求
| 要求 | 默认值 | 设置键 |
|---|---|---|
| 最小长度 | 8 个字符 | min_password_length(站点设置界面允许 6–32) |
| 大写字母 | 至少 1 个(A-Z) | require_uppercase |
| 数字 | 至少 1 个(0-9) | require_number |
| 特殊字符 | 不要求 | require_special_char |
| 小写字母 | 无此开关 | — |
| 不可复用 | 不能与最近 5 个历史密码相同 | password_history_count |
| 最小保留期 | 0 天(可立即再改) | password_min_age_days |
没有字典/弱密码检查,也没有密码强度指示器——校验结果以字段错误的形式返回。另有一条 bcrypt 限制:超过 72 字节的部分被忽略,所以超长密码的尾部字符不参与校验。
有效密码示例(满足默认策略):
MySecure#Pass2026!无效密码示例:
❌ 12345678 (无大写字母)
❌ abcdefgh (无数字)
❌ Pass123 (仅 7 位,短于默认 8 位)修改密码
- 打开个人设置(头像菜单)→ 账户安全 标签页。
- 找到修改密码区域,填写当前密码、新密码、确认新密码。
- 点击更新密码。
后端行为(POST /api/v1/users/me/change-password):
- 当前密码错误返回
2003(current_password_incorrect)。 - 未满足最小保留期(
password_min_age_days)返回5306,并带还需等待的天数。 - 不符合策略或命中历史密码返回
1001,errors.new_password中给出逐条原因(如password_recently_used)。 - 成功后刷新
password_changed_at、按策略重算过期时间、清除强制改密标记,并发送security.password_changed高优先级通知。
强密码建议:混合多种字符类型、长度至少 12 位、避免个人信息、使用密码管理器。
重置忘记的密码
前置条件:必须已配置 SMTP(smtp_enabled=true)。未配置时「忘记密码」直接返回 5007(smtp_not_configured)。
- 前往登录页,点击忘记密码?。
- 输入邮箱地址并点击发送重置邮件。为防枚举,无论邮箱是否存在都会返回成功。
- 查收邮件,两种方式任选:
- 点击邮件中的重置链接(跳转
/reset-password?token=...); - 或在页面上展开或手动输入验证码,填入邮件里的 6 位验证码。
- 点击邮件中的重置链接(跳转
- 输入新密码并确认,点击重置密码。
- 用新密码登录。
- 验证码/链接有效期 10 分钟;重发冷却 60 秒(
5008)。 - 验证码错误返回
5005,链接无效或过期返回5006。 - 重置不要求当前密码(凭证本身就是授权),但同样校验密码策略与历史;成功后账户的失败计数与锁定状态会被清除。
密码过期
若管理员启用密码过期策略(默认关闭):
| 设置键 | 默认值 | 含义 |
|---|---|---|
password_expiration_enabled | false | 策略总开关 |
password_expiration_days | 90 | 密码有效天数 |
password_expiration_warning_days | 7 | 到期前提醒窗口 |
password_history_count | 5 | 历史密码保留数量 |
password_min_age_days | 0 | 改密最短间隔 |
豁免对象:SSO 账户(auth_source != "local")、被单独标记豁免的用户(password_expiration_exempt)以及超级管理员,均不参与过期与强制改密。
时间线:
- 每日 08:00 运行过期检查:距到期正好 7 / 3 / 1 天时发送
password.expiring提醒;已过期则发送password.expired并设置强制改密标记(同一用户每天最多一次提醒)。 - 登录时若已过期,响应带
force_password_change=true与reason=expired,前端跳转/change-password?reason=expired。 - 个人设置的账户安全标签页会展示密码过期时间;已过期显示红色告警,剩余不足 7 天显示黄色预警(该阈值在前端固定为 7 天)。
TOTP 双因素认证
设置 TOTP
- 打开个人设置 → 账户安全 标签页,点击启用双因素认证。
- 向导第一步说明双因素认证的作用;第二步展示二维码(issuer 为
Clouisle),用身份验证器(Google Authenticator、Authy、Microsoft Authenticator、1Password 等)扫码,或手动输入密钥。 - 输入身份验证器当前的 6 位验证码完成校验(校验窗口为 ±1 个周期,即 ±30 秒)。
- 保存一次性备份码:向导一次生成 10 个,格式
XXXX-XXXX,可下载(clouisle-backup-codes.txt)或复制。 - 点击完成。
接口先调用 POST /api/v1/totp/setup 生成密钥、二维码与备份码,此时尚未启用;POST /api/v1/totp/enable 校验验证码后才真正启用。已启用时再次调用 setup/enable 返回 5314(totp_already_enabled);缺少待启用密钥时 enable 返回 5315(totp_setup_expired)。

TOTP 密钥用 SECRET_KEY 派生的密钥加密后存储。更换 SECRET_KEY 会导致所有已绑定的 TOTP 密钥无法解密,用户只能由管理员解绑后重新绑定。
使用 TOTP 登录
- 输入用户名和密码,后端返回
requires_totp=true与 5 分钟有效的临时令牌。 - 输入身份验证器中的 6 位验证码(或点击使用备份码改输备份码)。
- 点击验证。成功后临时令牌被替换为正式登录令牌。
验证失败返回 5311(totp_invalid);被限速时返回 5312(totp_rate_limited)并带 seconds,前端直接提示剩余等待秒数。限速规则:自首次失败起 300 秒窗口内累计 5 次失败即锁定 900 秒(15 分钟);成功验证后计数清零。
备份码
- 一次生成 10 个,格式
XXXX-XXXX,每个只能使用一次,服务端只保存哈希。 - 账户安全标签页显示剩余备份码数量(界面文案为
剩余 {count} 个备份码)。 - 点击重新生成备份码并输入当前 6 位验证码,即可作废旧码、生成新的一批(旧备份码立即失效)。
禁用 TOTP 与管理员操作
- 用户自行禁用:点击禁用双因素认证,在确认框中同时提供账户密码与当前验证码(或备份码)——两项都必须通过校验,密码错误返回
2003,验证码错误返回5311。 - 管理员解绑:
POST /api/v1/admin/totp/users/{user_id}/disable可直接为某用户关闭 TOTP,用于用户丢失验证器与备份码的场景(需要admin:dashboard:access权限)。 - 强制全员 TOTP:站点设置
require_totp=true时,未绑定用户登录会被重定向到/totp-setup完成绑定,不绑定则无法进入系统。
会话管理
会话时长
- 会话是无状态 JWT,有效期取
session_timeout_days(默认30天),没有空闲超时、也没有「记住我」选项。 - 令牌保存在浏览器
localStorage的access_token中,随请求以Authorization: Bearer <token>发送。
单会话模式
开启 single_session 后,新登录会把上一个令牌写入 Redis 黑名单并覆盖会话记录。
已知限制
认证链路只检查 Redis 黑名单,而登录时写入的黑名单条目 TTL 只有 5 秒;用于读取会话记录的 get_user_session 目前没有调用方。因此单会话模式实际只在约 5 秒内拒绝旧令牌,之后旧令牌仍可继续使用到其过期。不要把单会话模式当作踢出会话的安全手段。
注销
- 点击右上角个人资料图标。
- 选择退出登录。
- 跳转到登录页。
后端的行为是:把当前令牌加入 Redis 黑名单(TTL 5 秒)并清除会话记录;JWT 本身无状态,已复制到别处的同一令牌在 5 秒后仍会被接受,直到自身过期。真正生效的阻断手段是修改密码(并配合单会话)、停用账户或缩短 session_timeout_days。
账户安全
安全通知
以下事件会产生 security.* / password.* 站内通知:
| 事件类型 | 触发时机 | 级别 |
|---|---|---|
security.password_changed | 修改密码成功 | 高 |
security.account_locked | 连续失败触发锁定 | 高 |
security.login_anomaly | 新 IP / 新设备登录 | 高 |
password.force_change | 管理员要求下次登录改密 | 高 |
user.password_reset | 管理员为用户设置了新密码 | 中 |
password.expiring / password.expired | 到期前 7/3/1 天 / 已过期 | 中 |
定期查看通知中心 是发现未授权访问最直接的方式。
账户被盗用
若怀疑未授权访问:
- 立即修改密码。注意这不会作废已签发的 JWT(见注销),也不会影响已有的 API Key。
- 启用 TOTP,或重新生成备份码。
- 查看登录通知中是否有陌生 IP / 设备,并在API 密钥列表中停用可疑密钥。
- 联系管理员停用账户——
is_active=false会在认证阶段立刻拒绝该账户的所有请求,是唯一能立即止血的手段。轮换SECRET_KEY同样能让全部 JWT 失效,但会导致所有已绑定的 TOTP 密钥无法解密,请谨慎使用。
管理员设置新密码
管理员在用户管理中可以直接为用户设置新密码(PUT /api/v1/admin/users/{id} 带 password):
- 管理员设置新密码(会按密码策略校验,但不检查历史密码)。
- 系统向该用户发送
user.password_reset通知——不会发送含临时密码的邮件,新密码需要管理员通过安全渠道另行告知。 - 用户用新密码登录后应立即自行修改。
配套的管理员操作:强制修改密码(POST /api/v1/admin/users/{id}/force-password-change,用户下次登录必须改密)、重置过期计时(重置 password_changed_at)、免除过期策略(password_expiration_exempt)。
故障排除
无法访问登录页
- 检查网络连接与 URL 是否正确。
- 尝试其他浏览器并清除缓存与 Cookie。
- 确认
site_url/ 前端地址配置正确(SSO 回调也会用到)。 - 联系管理员。
登录提示用户名或密码错误
账号不存在、密码错误、SSO 账户尝试密码登录,返回的都是同一个 2003——这是反枚举设计,不代表系统故障。
- 确认使用的是用户名(精确匹配)或邮箱(大小写不敏感)。
- 若账户由 SSO 创建且从未设置本地密码,请改用 SSO 登录。
- 提示中若带
remaining_attempts,注意剩余尝试次数。 - 使用忘记密码重置。
账户已被锁定
- 等待锁定自动到期(默认 15 分钟)后重新登录,此时失败计数会归零。
- 管理员的激活/编辑操作不会清除
locked_until,没有「立即解锁」按钮;若急需恢复访问,可走忘记密码重置流程——重置成功会同时清除失败计数与锁定状态。 - 若反复被锁定,检查是否有旧脚本在重试错误密码。
未收到验证/重置邮件
- 确认
smtp_enabled=true且 SMTP 参数正确——未配置时接口直接返回5007。 - 检查垃圾邮件文件夹并等待几分钟。
- 注意 60 秒重发冷却(
5008会给出剩余秒数)。 - 确认邮箱地址与账户上的邮箱一致。
未收到验证码导致的邮箱未验证
登录时返回 5004 会直接进入验证步骤并自动重发一封验证码;页面上的重新发送按钮受 60 秒冷却限制。
由于管理端没有「标记邮箱已验证」的开关,若用户始终收不到邮件,请先让管理员确认 SMTP 配置(未配置时发送接口直接 5007);仍不可用时,可临时关闭 email_verification 让该用户先登录,待邮件通道恢复后再重新开启。
TOTP 无法验证
- 检查设备时间是否自动同步(±30 秒窗口)。
- 被限速时按提示等待,最多 15 分钟。
- 改用一次性备份码登录。
- 备份码用尽时联系管理员解绑后重新绑定。
被要求修改密码
说明 force_password_change 已置位(密码过期,或管理员强制)。在 /change-password 页面输入当前密码与新密码即可;改密成功后标记自动清除。
SSO 登录失败
- 确认使用的提供商与账户状态(停用/待审批会跳转到
/sso-callback并显示对应提示)。 - 检查提供商配置与回调地址(详见 SSO 配置)。
- 清除浏览器 Cookie 后重试,或改用密码登录(若站点允许)。
最佳实践
✅ 推荐
- 使用强而唯一的密码,并开启 TOTP。
- 使用密码管理器,不在多处复用同一密码。
- 保持邮箱地址有效,它是密码恢复的唯一通道。
- 处理安全通知,而不是清空通知列表。
- 优先用 SSO 登录,减少密码暴露面。
❌ 避免
- 与他人共享账户或密码。
- 在公共设备上保持登录(退出只影响本机令牌,且见注销的限制)。
- 在共享设备上关闭 TOTP。
- 忽略
security.login_anomaly告警。
相关页面
这篇文章对你有帮助吗?