保护接口和页面

先记住一件事

接口挂在 /api 下面不代表需要登录。路径只是路径,每个接口自己说要不要登录,没说的就是公开的。页面也一样,路由守卫只管浏览器跳转,接口不加认证的话直接请求照样能拿到数据。

接口只给登录用户

/api/reports 下面的接口都要登录。没登录返回 401。导出接口另外要求 reports:export 权限,没权限返回 403。补三种情况的测试:匿名、登录没权限、登录有权限。

Agent 会在接口前加认证中间件,需要权限的再加权限检查,两个按顺序放在同一条路由上。你会看到清晰的分工:401 是没登录,403 是登录了但不行。

在接口里知道当前是谁

加了认证以后,接口就能读到当前用户。最常见的用法是把数据和他绑定:

创建订单时把当前登录用户记为创建人。不要信请求体里传来的用户 ID。

用户身份只从服务端会话里取。浏览器传来的「我是谁」一律不可信,Agent 知道这一点,但你审核时也可以留意。

访客也能看,登录后不一样

有些接口对谁都开放,只是登录用户多看到一点:

商品列表访客也能看,登录用户额外返回自己有没有收藏。

这种用「登录可选」的方式:有会话就带上,没有也不拒绝。它不是保护手段,别拿它当保护用。

页面要不要登录

页面在 client/routes.ts 里声明三种之一:

  • required:没登录跳到登录页,业务页面基本都是这个;
  • guest:已登录跳回首页,登录、注册这类访客页面用;
  • optional:谁都能看。

子页面跟着父页面走。跟 Agent 说的时候把页面和它调的接口一起说:

加一个 /reports 页面,要登录。页面里调的接口也要登录。

账号被禁用以后

管理员在用户管理里禁用某人:

  • 他再登录会收到 403,错误码 ACCOUNT_DISABLED;
  • 他正在用的会话立即失效,下一次请求就是 401;
  • 实时连接被断开。

这些都是插件内置的行为,业务代码里不用再查一遍「是否启用」。重新启用后他需要重新登录。

验收

  • 匿名请求受保护接口返回 401;
  • 登录但无权限返回 403,不是 401;
  • 没登录访问 required 页面被带到登录页,登录后访问 guest 页面被带回首页;
  • 退出后旧 Cookie 失效;
  • 测试、typecheck 和构建通过。