后端开发中如何设计安全可靠的用户认证
结论:后端认证的安全基线是密码慢哈希、服务端会话或短时效令牌、全链路 TLS、登录限流、MFA 兜底,并把“认证”和“授权”彻底分开。下面按可落地参数展开。
用户密码到底该怎么存?
结论:密码只能存慢哈希,首选 Argon2id,其次 bcrypt cost≥12 或 scrypt N=2^15、r=8、p=1;禁止明文、MD5、SHA1、SHA256 单次哈希和可逆加密。
Argon2id 推荐参数为 m=64MiB、t=3、p=1;服务器内存充足可提升到 m=256MiB、t=3、p=1。哈希函数自带盐值,不需要开发者手写盐。额外 pepper 应存入 KMS 或环境变量,不能和数据库同库保存。登录校验使用恒定时间比较,失败统一提示“用户名或密码错误”。
密码策略参考 NIST SP 800-63B:最少 8 位,最大至少允许 64 位,允许空格和所有字符,不强制每 90 天更换。接入泄露密码库,命中已泄露密码直接拒绝注册或要求重置。
登录态用 Session 还是 JWT?
结论:传统浏览器 Web 优先服务端 Session;移动 App、API 网关、多服务调用可用短时效 JWT + 刷新令牌。
Session ID 用 CSPRNG 生成至少 128 bit 随机值,存 Redis,TTL 设为 30 分钟滑动过期,登出立即删除。Cookie 设置 HttpOnly、Secure、SameSite=Lax;跨站场景用 Strict;固定域名可用 __Host- 前缀。
JWT 只放 sub、exp、iat、jti、scope,不放手机号、身份证、角色明细。access token 有效期 15 分钟,refresh token 7 天且每次刷新必须旋转,旧 refresh token 立即失效。签名用 RS256 或 ES256;HS256 的密钥至少 256 bit 随机。撤销依赖短 TTL + jti 黑名单或令牌版本号。
如何防止撞库、枚举和暴力破解?
结论:登录接口必须做 IP + 账号双维度限流、失败退避、验证码和 MFA。
同一账号连续 5 次失败后锁定 15 分钟或指数退避;同一 IP 每分钟超过 20 次登录请求直接拒绝。错误消息统一为“用户名或密码错误”,响应时间保持同一量级,避免通过时间差枚举账号。
MFA 用 TOTP,时间窗 30 秒;高价值账号用 WebAuthn/FIDO2。审计日志记录时间、IP、User-Agent、账号、结果、失败原因,保留 180 天。异常登录触发邮件或短信告警。
OAuth2/OIDC 接入怎么做才安全?
结论:第三方登录只用授权码模式 + PKCE,禁用隐式流和密码模式。
PKCE 的 code_verifier 用 43-128 字符随机串,challenge 用 S256。授权请求必须带 state 并校验,OIDC 还要校验 nonce。redirect_uri 必须精确白名单匹配,禁止通配符。
拿到 ID Token 后校验签名、iss、aud、exp、nonce。永远不要把前端传来的 user_id 直接当作已认证身份。第三方登录只负责证明“你是谁”,不直接授予业务权限。
认证和授权怎么分开?
结论:认证回答“你是谁”,授权回答“你能做什么”,两者代码和存储分开。
JWT 里的角色只做粗粒度网关拦截,服务端操作资源时必须二次校验归属。权限模型用 RBAC 或 ABAC,默认拒绝,最小权限。服务间调用用 mTLS 或短期服务令牌,令牌绑定 audience。
查询资源时用 user_id + resource_id 联合条件,防止 IDOR 越权。例如删除订单必须同时匹配当前用户 ID 和订单 ID,不能只按订单 ID 删除。
上线前必须检查哪些项?
结论:上线前至少逐项确认以下 8 条。
- TLS 1.2+,优先 TLS 1.3,HSTS 开启。
- 密码哈希参数压测后落在 100-300 ms。
- 登录、注册、重置密码接口全部限流。
- Cookie 带 HttpOnly、Secure、SameSite。
- JWT 有效期和刷新旋转已生效。
- MFA 可启用,恢复码一次性。
- 密钥放 KMS 或环境变量,90 天轮换。
- 审计日志接入告警,异常登录 5 分钟内通知。
认证安全不是单点问题,核心是慢哈希、短时效、限流、MFA、最小权限和审计。按上述参数落地,能挡住撞库、枚举、令牌泄露、越权四类高频风险。
原文链接:https://www.gj0.com/thread-84.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。