agilelabs-fx-docs main Solution/authentication/accesscode-jwt-login.md

AccessCode + JWT 登录方案

本页总结 /root/gitrepos/mkdocs-net 当前管理端的认证实现。它的核心目标不是做完整账号体系,而是给后台提供一个低成本、可快速部署的管理员登录入口。

适合看什么

  • AccessCode 如何作为后台登录入口使用。
  • 后端如何把 AccessCode 校验结果转换成 JWT。
  • 前端如何保存 token 并恢复登录态。
  • 当前实现和传统用户名密码登录共存的方式。

方案总览

mkdocs-net 的管理端认证链路分两段:先登录拿到 JWT,再用 JWT 访问后台接口。登录接口同时支持两种输入:

  • AccessCode
  • Email + Password

其中当前前端管理页只暴露 AccessCode 输入框,因此实际管理端默认走的是 AccessCode 登录链路。

sequenceDiagram
    participant Admin as AdminWeb
    participant Account as /api/account/login
    participant Config as AdminWebSettings
    participant Jwt as JWT Generator

    Admin->>Account: POST { accessCode }
    Account->>Config: 读取 AccessCode / AdminEmail / AdminUserId
    Account->>Account: 比较 accessCode
    alt 校验成功
        Account->>Jwt: 生成 token
        Jwt-->>Account: token + expiresIn
        Account-->>Admin: id + email + token + expiresIn
    else 校验失败
        Account-->>Admin: Wrong access code
    end

后端登录入口

登录接口是 POST /api/account/login。它按请求内容走两条分支:

  • 请求里带 AccessCode 时,进入 LoginWithAccessCodeAsync
  • 没有 AccessCode 时,要求同时提供 EmailPassword

这意味着后端认证模型本身并不排斥用户账号密码登录,只是当前管理前端把主入口收敛成了 AccessCode。

AccessCode 校验逻辑

AccessCode 登录依赖 AdminWebSettings

  • AccessCode
  • AdminEmail
  • AdminUserId

后端会先检查 AccessCode 是否已配置,再用字符串全等比较请求值和配置值。校验通过后,不查询用户表,而是直接用配置里的管理员身份信息拼出登录结果,再继续生成 JWT。

这说明当前 AccessCode 更接近“共享管理员口令”,而不是“用户个人凭证”。

JWT 签发方式

登录成功后,后端统一调用 GenerateToken 生成 JWT。当前 token 里包含的核心 claims 很少:

  • ClaimTypes.NameIdentifier:用户 Id
  • ClaimTypes.Name:显示名,这里实际放的是邮箱
  • jti
  • iat

签发参数来自 TokenSettings

  • Issuer
  • Audience
  • ExpirationMinutes
  • SigningKey

签名算法是 HmacSha256。token 默认有效期是 480 分钟,也就是 8 小时。

邮箱密码登录的兼容路径

如果请求没有 AccessCode,接口会走邮箱密码登录分支:

  • 先按邮箱查用户。
  • 如果用户存在但还没有 PasswordHash,会用本次输入密码初始化 salt 和 hash。
  • 后续再按 SHA256 + salt 比较密码。

这个分支说明项目底层保留了用户表和密码校验能力,但当前管理端 UI 没把它作为主入口。

前端登录态实现

adminweb 的做法很直接:

  • 登录页只显示一个 Access Code 输入框。
  • 提交后调用 POST /api/account/login,请求体只传 { accessCode }
  • 登录成功后,把返回的 token 写入 localStorage,key 为 mkdocs.admin.token
  • 页面启动时先从 localStorage 读取 token。
  • 如果本地已有 token,就调用 /api/account/user_info/api/doc_project/search 恢复会话。

所有管理请求都复用统一的 request() 方法,在有 token 时自动附加:

Authorization: Bearer <token>

如果 token 失效或接口返回错误,前端会清空本地登录态并回到登录页。

关键配置点

需要重点关注的配置有两组:

配置组 作用 当前含义
AdminWebSettings AccessCode 登录入口 共享管理员身份
TokenSettings JWT 签发与校验 issuer、audience、过期时间、签名 key

生产环境至少要做到:

  • 不保留示例默认 AccessCode
  • 不保留示例默认 SigningKey
  • 把配置放到安全的环境级配置源,而不是提交到公共仓库。

适用场景与边界

这个方案适合:

  • 内部后台。
  • 管理员数量少的系统。
  • 需要快速落地、暂时不做完整账号体系的项目。

这个方案的边界也很明确:

  • AccessCode 是共享口令,不是用户级身份凭证。
  • 登录成功后得到的是后台通行凭证,不区分细粒度角色。
  • token 落在 localStorage,实现简单,但安全边界弱于更严格的会话方案。

推荐搭配阅读

相关页面