JWT 保护后台接口方案
本页总结 /root/gitrepos/mkdocs-net 当前管理端的授权实现。这里的“授权”不是细粒度角色权限,而是“请求是否已经通过 JWT 认证、能否进入后台管理接口”。
适合看什么
- 后台接口如何统一要求已登录。
- JWT Bearer 在服务端如何完成校验。
- 当前授权模型的粒度和边界。
- 为什么这套实现更适合轻量后台,而不是复杂权限平台。
授权模型结论
mkdocs-net 当前的授权模型可以概括成一句话:
登录成功并携带有效 JWT,就拥有后台管理接口的访问权限。
它具备这些特点:
- 有认证后的接口保护。
- 没有角色区分。
- 没有策略名和权限点。
- 没有资源级、项目级、菜单级授权裁剪。
因此更准确的表述是“粗粒度后台授权”,不是 RBAC,也不是 ABAC。
接口保护方式
后台项目管理接口集中在 api/doc_project/*,控制器类级别直接标了 [Authorize]。这意味着下面这些接口都默认要求已登录:
POST /api/doc_project/searchGET /api/doc_project/getPOST /api/doc_project/addPOST /api/doc_project/updatePOST /api/doc_project/delete
此外,POST /api/account/register 也带 [Authorize],说明即使是注册新用户,也被视作后台受控操作,而不是开放注册入口。
与之对应,匿名入口主要只有:
POST /api/account/login
JWT 校验链路
服务端在 ServiceRegister 里显式注册了 JWT Bearer 认证。校验参数来自 TokenSettings,核心包括:
ValidateIssuerSigningKey = trueValidateIssuer = trueValidateAudience = trueValidateLifetime = trueClockSkew = 1 minute
同时设置了:
NameClaimType = ClaimTypes.NameRoleClaimType = ClaimTypes.Role
虽然 RoleClaimType 已配置,但当前签发 token 时并没有放入角色 claim,所以它还没有形成真正的角色授权链。
请求管道接入位置
认证授权中间件在请求管道里一起接入:
UseAuthentication()UseAuthorization()
这一步发生在 endpoint 配置之前,因此控制器上的 [Authorize] 能正常生效。如果缺少这一步,控制器特性本身不会自动完成鉴权。
前端如何配合授权
前端管理端不做单独的权限计算,行为很直接:
- 本地没有 token,就显示登录页。
- 本地有 token,就给后台请求统一附加
Authorization: Bearer <token>。 - 用
/api/account/user_info和项目查询接口验证 token 是否还有效。 - 一旦请求失败,就清空本地会话并回到登录页。
这说明前端没有菜单级权限控制,也没有基于 claims 的界面裁剪。它只关心“当前 token 能不能继续访问后台接口”。
当前实现没有做什么
为了避免误判,需要把未实现的能力明确写出来:
- 没有
[Authorize(Roles = ...)]。 - 没有 policy-based authorization。
- 没有按项目、组织、租户做资源隔离。
- 没有基于 claims 的按钮级或页面级授权。
- 没有 token 黑名单或服务端会话撤销机制。
TokenSettings 里虽然有 IsVerifyTokenPerRequest 和 SessionMemoryCacheSeconds,但当前代码里没有把它们真正串成“每次请求都回源校验 session”的闭环。
适用场景与限制
这套授权方式适合:
- 单管理域后台。
- 管理员范围较小的内部系统。
- 先把后台入口保护起来,而不是先建设复杂权限中心的项目。
它的限制也很明显:
- 只解决“未登录不能进”,不解决“登录后谁能做什么”。
- AccessCode 登录成功后的管理员身份是共享的,不适合审计要求高的场景。
- 一旦需要多角色、多租户或资源级权限,就需要在现有 JWT 认证之上继续扩展授权模型。