LESSON 7.1 / PRODUCTION

登录、会话与权限

认证回答“你是谁”,授权回答“你能做什么”。按钮是否显示不能代替服务端权限检查。

预计阅读15–20 分钟
完成结果所有敏感操作都有服务端身份与权限依据。
本课目标
  • 所有敏感操作都有服务端身份与权限依据。
  • 密码哈希、会话、Cookie 和令牌
  • 保护一个管理接口,分别验证匿名、普通用户和管理员三种结果。
开始之前
  • 完成 6.4「Redis 与缓存:什么时候才需要」
01

FOUNDATION

必须理解

认证回答“你是谁”,授权回答“你能做什么”。按钮是否显示不能代替服务端权限检查。

认证确认“你是谁”,会话让后续请求记住身份,授权决定“你能做什么”。登录页只是入口,真正安全边界必须在每一次服务端数据操作中执行。

先建立整体直觉

进入办公楼先用证件确认身份,这是认证;领取临时门卡维持会话;不同楼层门禁决定授权。看到某扇门不代表有权打开。

贯穿本课的实际场景

用户登录后获得安全会话;查询、更新或删除任务时,服务端都用会话中的 userId 限制 ownerId,绝不相信前端传来的“这是我的任务”。

概念 1

密码哈希、会话、Cookie 和令牌

先用白话理解

认证是在确认“你到底是谁”,可以用密码、第三方账号或登录链接完成。密码不能明文保存,也别自己发明加密方法,成熟认证库已经处理了大量容易踩坑的细节。

基础概念

认证确认访问者是谁,会话让后续请求持续关联这个身份。密码应经过专用密码哈希算法处理,Cookie 或令牌只承载会话凭证,不应直接保存明文密码。

进一步理解

注册时保存带盐密码哈希;登录时用同一算法验证。成功后服务端建立会话,浏览器通过安全 Cookie 在后续请求中携带会话标识。

HttpOnly 限制脚本读取 Cookie,Secure 要求 HTTPS 传输,SameSite 降低部分跨站请求风险。它们各防一类问题,不能互相替代。

放进实际场景

用户登录任务应用后获得会话 Cookie;每次读取任务,服务端从会话取得 userId,而不是要求前端重复发送密码。

容易混淆的地方

哈希不是可逆加密,会话令牌也不等于用户身份本身;服务器仍需验证令牌有效、未过期且未撤销。

这一小节记住:密码只用于证明身份,会话用受控凭证延续身份。

概念 2

角色、资源所有权和最小权限

先用白话理解

用户登录一次后,网站需要在后续请求中认出他,这就是会话。安全 Cookie 常用来携带会话信息,HttpOnly、Secure 和 SameSite 分别挡住一部分常见风险。

基础概念

授权决定已认证身份可以执行哪些操作。角色描述一类权限,资源所有权限制具体记录,最小权限原则只授予完成当前任务所需能力。

进一步理解

管理员角色可以管理全局配置,普通用户只能操作自己的任务。即使两人调用同一路由,查询条件和业务规则也必须根据身份缩小范围。

权限检查应发生在服务端每个敏感操作上,并尽量靠近数据访问。隐藏按钮只能改善界面,无法阻止自制 HTTP 请求。

放进实际场景

更新任务时查询条件同时包含 taskId 与会话 userId;普通用户即使猜到他人 id,也更新不到记录。

容易混淆的地方

认证成功不代表拥有所有权限,角色也不能替代资源归属;“已登录”只解决你是谁,没有回答你能操作哪条数据。

这一小节记住:每次敏感操作都用服务端身份回答:这个人能否对这条资源做这件事?

概念 3

登录、退出、过期和找回流程

先用白话理解

授权回答的是“这个人能不能做这件事”。按钮藏起来只影响页面,真正的判断必须在服务端做,因为别人完全可以绕过页面直接请求 API。

基础概念

完整身份流程包括登录、退出、会话过期和账户找回。每条路径都在改变谁能继续使用账户,因此必须设计安全反馈、撤销和异常状态。

进一步理解

退出应让当前会话失效;过期后引导重新认证并尽量保存未提交工作;找回流程使用短期、一次性令牌并避免泄露账户是否存在。

修改密码、发现异常或管理员封禁时,可能需要撤销其他会话。重要操作可要求近期重新认证,而不是无限信任旧会话。

放进实际场景

用户找回密码后,重置链接立即失效,旧会话按策略撤销;返回登录页时不暴露该邮箱是否注册。

容易混淆的地方

“记住我”不是永不过期;延长会话会增加被盗后的风险,需要设备管理、撤销与重新认证配合。

这一小节记住:身份系统要覆盖进入、持续、离开和恢复,而不只是一个登录表单。

02

AI COLLABORATION

AI 如何参与

让 AI 对每个写操作说明服务端如何确认身份和权限,并列出越权测试。

推荐协作顺序

  1. 1

    先让 AI 画出登录、会话和授权三段流程,不生成加密算法。

  2. 2

    选择成熟认证库后,只参考当前版本的官方接入方式。

  3. 3

    用两个测试账户让 AI 帮你设计越权用例,再亲自验证服务端结果。

可直接使用的 Prompt
请为 Next.js + PostgreSQL 的任务应用设计最小认证与授权流程。使用成熟认证库,不自行发明加密。画出注册/登录、创建会话、读取当前用户任务、删除任务四条流程,并标出每一步的信任边界和失败状态。
应该得到什么

服务端从可信会话取得 userId,每次数据查询都带 ownerId;错误区分未登录与无权限,但不泄露其他用户资源是否存在。

人工检查清单

  • 确认密码不进入日志或客户端包,Cookie 属性安全,授权不是只在前端执行。
  • 要求 AI 为每个读写接口标出身份来源、授权规则和越权测试。
  • 用匿名、普通用户、资源所有者和管理员四种身份实际请求,确认服务端结果而非按钮可见性。
03

COMMON TRAPS

常见误区

错误不是需要隐藏的失败,而是帮助你看清系统边界的证据。下面三类问题在 AI 辅助学习中最常出现。

误区 1

登录成功就以为权限没问题

你会看到
用户能进入页面,也能通过改 URL 访问别人的任务。
为什么发生
明文或快速普通哈希无法抵抗数据库泄露后的离线猜测;隐藏入口又无法阻止直接构造请求。
怎样纠正
每次服务端读写都按当前会话和资源归属重新授权。
误区 2

自己实现密码和令牌

你会看到
用普通哈希或自定义字符串拼出会话,留下严重风险。
为什么发生
信任请求体中的 userId 或 role 等于允许调用者自己声明身份和权限。
怎样纠正
使用成熟认证库和专用密码哈希,不发明安全协议。
误区 3

只在前端隐藏按钮

你会看到
页面看不到删除按钮,但直接调用 API 仍能删除。
为什么发生
只实现登录成功路径,会遗留无法撤销的会话、可复用重置链接和过期后的糟糕恢复体验。
怎样纠正
前端控制展示,服务端控制真正权限,两处职责不能互换。
04

HANDS-ON

动手任务

保护一个管理接口,分别验证匿名、普通用户和管理员三种结果。

准备条件
  • 完成 6.4「Redis 与缓存:什么时候才需要」

跟着做

  1. 01

    画出认证、会话、授权三者关系。

  2. 02

    选择适配 Next.js 的成熟认证方案并阅读官方指南。

  3. 03

    实现登录和退出,检查 Cookie 的安全属性。

  4. 04

    把任务查询改为按当前 userId 过滤。

  5. 05

    用两个测试账户尝试访问彼此任务并确认被拒绝。

完成标志

所有敏感操作都有服务端身份与权限依据。

加餐挑战

设计“忘记密码”流程,标出令牌有效期、一次性使用和避免暴露账户存在性的要求。

离开本课前,自问四件事

  • 认证、会话与授权分别回答什么问题?
  • 密码哈希、Cookie 属性和会话撤销各自防什么风险?
  • 为什么隐藏管理按钮不能作为权限控制?
  • 登录、退出、过期和找回流程分别需要哪些服务端保证?
完成本课了吗?

确认完成后,会同步更新学习中心的课程学习进度。