avatar

AgCl

auth系统的搭建

2025-09-06

关于auth

auth系统也就是身份认证系统,用与验证我们用户身份的一种软件机制,确保只有相应权限的用户才能使用特定的功能。

现如今已经有了众多的auth库,如今广受好评的better-auth,nextJS最推荐的next-auth都提供了非常方便的OAuth、会话管理、安全性保障等机制。毫无疑问它们都是优秀的auth库,但对于本博客的需求,这些auth库都过于庞大,再加上本博客的需求模块对于用户身份的识别不依赖于电子邮箱、手机号等个人信息或者OAuth,且大部分auth库都强关联电子邮箱,所以决定自己实现一套简单的auth系统。

jwt与session

概述

jwt是无状态的的令牌,它存储于客户端,服务端不做存储只做验证。

session是有状态的令牌,它存储于服务端,客户端只记录session ID用于服务端查询session。

组成

jwt由三部分组成:Header(头部,描述算法和类型)、Payload(载荷,包含用户信息)、Signature(签名,用于验证完整性)。

session由两本组成:session ID和session Data。session Data理论上可以存储任意内容,常见内容包括:用户ID、权限、登陆时间...

jwt

优点

  1. 服务端无状态
    • 不需要存储用户会话,特别适合微服务、分布式系统。
  2. 跨平台、跨域支持好
    • 可以存储在任意地方(header、localStorage、Cookie),移动端、Web、第三方服务都能用。
  3. 性能好
    • 服务端只需验证签名,无需查询数据库/缓存获取 Session。
  4. 自包含信息
    • JWT 内部可以包含用户角色、权限等信息,减少额外查询。

缺点

  1. 不可撤销
    • JWT 一旦签发,在过期前都有效,服务端无法单方面让它失效(除非维护黑名单)。
    • 不适合需要频繁踢人、手动注销的场景。
  2. 安全性问题
    • 如果 JWT 被盗,攻击者可一直使用,直到过期。
    • 必须使用 HTTPS 传输,并妥善存储(避免 XSS/CSRF)。
  3. 体积较大
    • JWT 携带了用户信息,每次请求都会带上,增加网络开销。
  4. 刷新机制复杂
    • 一般需要 短期访问 token + 长期刷新 token 机制,增加了实现复杂度。

Session

优点

  1. 安全性较高
    • 用户数据存储在服务端,不易被篡改。
    • 即使 Session ID 泄露,也可以在服务端快速失效处理(如删除 Session)。
  2. 便于管理
    • 服务端可以手动失效/销毁用户的会话。
    • 支持服务端主动踢用户下线、限制登录次数等。
  3. 适合传统 Web 应用
    • 浏览器天然支持 Cookie,会话保持简单方便。

缺点

  1. 服务端有状态
    • 每个用户的会话信息要保存在服务器上,用户量大时会占用内存或需要额外的存储服务(如 Redis)。
  2. 扩展性差
    • 多服务器部署需要共享 Session(使用 Redis/Memcached 等),增加了复杂度。
  3. 跨平台支持不友好
    • 移动端或跨域时使用不如 JWT 灵活,需要额外处理 Cookie 问题。

auth系统设计

本博客对于auth系统的需求很简单:

  • 用户的注册与登陆
  • 用户权限控制
  • 用户的身份识别

只需要以上基本功能,就能满足我目前需求模块的要求。

在基于很多文档的查询和jwt令牌认证的实践下,我还是采用了session的会话机制。这样就能更好的满足与我获取用户信息和服务端渲染的需求。