安全认证与会话管理把第三幕讲过的漏洞要点凝结成一套可落地的清单:密码用加盐强哈希、会话令牌随机且写 Cookie 加 HttpOnly/Secure、合理超时与注销即失效、关键操作二次验证、MFA 加持。目标是让“证明你是谁”这道闸尽量少被绕过,即使已被绕过也要尽量小后效。
第五幕的第二个装具盒把认证会话从“一个个坑”升级为“一套打法”。第三幕我们看它怎么崩,这一节反过来说怎么修——不是罗列清单,而是按“凭证、会话、失效、复核”四个环节串成环环相扣的体系。
密码存储的硬标准是“单向 + 加盐 + 抗爆破”。单向指不可逆哈希,加盐让同样的密码得到不同哈希、查表失效,抗爆破指算法要带工作因子(bcrypt、scrypt、Argon2),因为 GPU 并行爆破普通哈希很快。同时要拒绝弱口令、对关键账号(管理员)强制强口令、配合复用监测及时发现撞库泄漏。
from argon2 import PasswordHasher ph = PasswordHasher() hash1 = ph.hash("correct horse battery staple") # 每次结果都不同, 加盐 ok = ph.verify(hash1, "correct horse battery staple")
要点:哈希展示每次不同,是盐在起作用;校验用同一库的 verify,不做自定义拼接。
登录后发会话令牌,写进 Cookie 时三件事必须同时做对:
三件缺一,就可能在 XSS(可读令牌)、MITM(明文传输)、CSRF(跨站携带)中泄一道。尤其 HttpOnly 与 Secure 成本低收益高,属于必配。
信任不能永久有效。要给会话设两条期限:空闲超时(一段时间没操作就掉线)与绝对超时(登录太久了强制重登)。用户点注销时,服务端必须真的作废会话 + 使相应 Cookie 失效,而不是只在界面隐藏。密码被重置后,旧会话一律作废。
对支付、转账、改绑手机、改密这类高风险动作,即使在已登录会话里,也要再次验证身份(重输密码、验证码、二次因子)。它的价值是:就算会话令牌被窃,攻击者也无法在缺少第二道证明的情况下完成高价值操作。配合 MFA,把“盗号”的杀伤力大幅压低。
⚠️ 常见坑:会话令牌存 Cookie 就忘了加 HttpOnly 与 Secure;或注销只在客户端清 token 而服务端没作废;或重置口令后旧会话仍可用。这三处是最常见的“看似做了其实没做”点。
背景:一个登录应用,Cookie 无 HttpOnly 且注销不彻底。操作:开发者工具读会话 Cookie、注销后检查服务端会话是否仍有效。结果:脚本可读令牌、注销后会话仍能复用。解读:认证发证链和失效链都有缺口。变式:补 HttpOnly/Secure/SameSite、服务端注销即作废并重定 cookie;对登录接口加限频、关键操作加复核。重复操作后窃与会话复用路径全部失效。
凭证、会话、失效、复核把“用户登录后”的链路兜住了,但身份枢纽还要再对两类“不在用户眼前的账”负责。一是有账号生命周期管理:入职开账号、离职销号、权限变更要有流程,僵尸账号同样是攻击者的墙角,员工离职后长期不回收的会话和密码是潜伏风险。二是异地/异常行为可观测:连续异地登录、同一个号换设备、登录时间段反常,都可能提示令牌被借用,能不能在事后从审计日志里还原出“谁什么时候在哪个入口用什么方式登过”决定你能否定位盗号源头。把这两类账并进来,身份枢纽才算从“登录那一刻安全”走向“身份全生命周期安全”。
前面七个环节,单独记容易漏,给一张能贴进登录与鉴权模块评审的对照表,四行各自成一项:凭证行写“密码加盐强哈希、拒绝弱口令、工作因子到位”;会话行写“令牌随机、Cookie 带 HttpOnly/Secure/SameSite、绑定身份”;失效行写“空闲超时 + 绝对超时、注销即服务端作废、改密后旧会话全清”;复核行写“高风险动作二次验证、可配 MFA、登录限频防爆破”。任何改到登录与会话的改动,先逐行对表确认没有越界再合入。这张表和第七节的“生命周期账”合起来,就覆盖了“登录那一刻如何发证”和“发证之后如何维持与收口”两半。你会发现它本质上在反复强调同一件事:认证不是“对了就放你进来”,而是从发证到失效每一步都值得确认“这真的是你”的持续校验。