JWT 与会话认证
了解基于会话和 JWT 认证之间的差异。探索权衡点、优势和用例以为你的应用选择合适的认证方案。
了解基于会话和 JWT 认证之间的差异。探索权衡点、优势和用例以为你的应用选择合适的认证方案。
通常来说,使用应用程序的第一步是认证,用户提供身份凭证以成功登录。在这一步之后,身份系统(即身份提供者,认证服务器等)即可知道用户是谁以及他们有权访问哪些资源。
由于 HTTP 本质上是无状态的,会话中的每个请求都是独立的,不会记住之前请求的信息。为每一个操作重新认证用户是繁琐的,并且损害了用户体验。
接下来我们来了解 基于会话的认证 和 JWT (JSON Web Tokens) 认证,这两种方法都是保持认证状态的流行手段。每种方法都有其独特的优势和权衡点,两者之间的选择取决于你的应用程序的具体需求。如果你正在这两者之间做出选择,那么这篇指南可以帮到你。
基于会话的认证依赖于 服务器 维护用户的认证状态记录。通过创建和管理会话,服务器使用户能够在不必每次请求都重新输入凭证的情况下,继续登录并与应用程序交互。
会话创建
SessionID 存储在数据库中,并作为cookie 返回给用户的客户端。会话验证
SessionID)。SessionID。会话可以实时失效,这在需要快速撤销访问的情况下十分方便。
JSON Web Tokens (JWTs) 采取不同的方法,通过使用 JSON 对象将所有相关的用户信息直接嵌入到一个令牌中。与基于会话的方法不同,JWT 是无状态的,意味着服务器不管理认证记录。
一个 JWT 包含三部分:一个头、负载和签名。

JWT 发行
基于会话的工作流遵循类似的过程。然而,在认证之后,用户信息存储在服务器的会话中,而 JWT 依赖于发送给客户端以进行存储和后续使用的令牌。
令牌验证
Authorization 头中发送 JWT (Bearer <token>)。基于会话的认证要求服务器查询会话存储,这可能很慢,特别是如果它依赖于外部或集中化的数据库。相比之下,JWT 认证是无状态的,所有必要的信息都存储在客户端令牌中,并利用签名确保安全。这消除了会话管理的需要,使其更快速且更易于扩展,特别是在分布式系统中。
在客户端,注销通常意味着清除本地会话并从存储中移除令牌(ID 令牌、访问令牌、刷新令牌)。然而,对于 JWT 认证,这只是在本地解除用户的登录,而集中化的会话在授权服务器上仍然保持有效。因此,直到令牌过期或被手动终止,用户可能仍可以访问同一会话下的其他应用程序。
撤销 JWT (JSON Web Token) 比基于会话的认证更具挑战性,因为 JWT 是无状态的,一旦发出便无法失效,除非实施特定的策略。常见方法包括:
exp 声明(例如,15 分钟)。一旦过期,用户必须重新认证。如果令牌被泄露,这会将风险降到最小,因为攻击者只能在有限的时间内使用该令牌。为了保持无缝的用户体验,刷新令牌 可以用来减少重新认证的不便。JWT 不能实时更新
一旦 JWT 签署,它不能被撤销或更新,并且将被视为有效,只要签名有效且未过期。
如果用户的访问权限更改(通常是降级),用户将仍然具有访问已移除资源的权限,直到 JWT 过期。同样,如果 JWT 包含基于角色的授权信息,新的授权范围将在旧的 JWT 过期之前不会生效。换句话说,JWT 不适合实时撤销,用户可以设置适当的过期时间来减轻这一问题。
多设备和撤销难题
在 JWT 过期之前无法验证所有已发出的 JWT,以使用户撤销所有设备。虽然理论上可以撤销签名密钥使 JWT 失效,但这也会使所有使用该密钥的 JWT 失效,处理缓存密钥的过程会使这种方法对于简单的用户撤销操作不太实际。
一些身份提供者可能有这些 JWT 问题的预构解决方案。有关更多信息,请查看"改善 JWT 认证体验的最佳实践”
会话和 JWT 是在无状态的 HTTP 世界中持久化认证和授权上下文的两种流行方法。虽然两种方法都有自己的优缺点,但它们提供了不同的优势和缺陷。
会话提供了对单个请求授权的更强保证,并且易于安全实现。然而,它们对服务器侧数据库验证的依赖引入了延迟开销,这可能会对高响应性应用的用户体验产生负面影响。
另一方面,JWT 有利于更快的授权和与外部应用的互操作性,但需要更多开发人员的努力来解决安全复杂性。例如,我们可以使用 webhook 来通知客户端用户的访问被撤销,以便客户端可以清除缓存的 JWT 并强制用户重新认证。
由于基于令牌的认证更适合扩展并且其缺点仍然可控,它越来越多地被现代应用采用。
你的认证方法应匹配你的应用的架构和具体需求。以下是一个快速指南以帮助你决定:
基于会话的认证最适用于需要实时会话控制、集中管理或可扩展性不是主要关注点的场合。以下是它适用的场景:
持久会话的 Web 应用
对于如在线购物网站,会话是跟踪用户,购物车和偏好设置所必需的。
需要实时会话控制的应用
银行或金融服务等应用得益于服务器控制的会话数据,确保健壮的访问管理和安全性。
单服务器或小规模系统
没有高可扩展性需求的内部工具或小规模应用依赖于简单的会话管理以获得易用性和可靠性。
JWT 认证更适用于优先考虑可扩展性、效率和分布式系统的应用。它特别适用于客户端和服务器之间的无状态交互。考虑为以下场合使用基于令牌的认证:
单点登录 (SSO)
JWT 非常适合 单点登录,允许用户只需认证一次,即可无缝访问多个服务或应用。分享关于使用 OAuth 2.0 和 OIDC 保护基于云的应用程序的详细解释,使用 JWT 格式作为访问令牌和 ID 令牌。
移动应用
移动应用通常偏向于使用 JWT 进行认证,因为令牌可安全地存储在设备上,并随每个 API 请求发送。探索适用于 Android / iOS 快速集成 JWT 认证。
微服务架构
在微服务环境中,JWT 允许每个服务独立验证令牌而不依赖于中心化的会话存储,确保可扩展性和效率。
跨域认证
JWT 在涉及多个域或子域(例如 api.example.com,dashboard.example.com 和 docs.example.com)的情况下表现出色。与 cookies 不同,JWT 允许跨域认证而无需额外的依赖。
API 和 Web 服务
RESTful API 和 Web 服务通常使用 JWT 进行认证,因为它们轻量级、便携且消除了服务器端会话管理的需求。了解更多关于机器对机器认证用于应用直接与资源通信的场合。
JWT 认证是一个强大的工具,但可能伴随着一些影响用户体验的挑战。Logto 提供了一个轻松且可靠的解决方案来克服这些障碍,使其成为安全高效认证的首选。
JWT 认证的一个常见问题是确保适当的用户注销体验。Logto 用其现成的 SDK 简化了这一过程。
这确保了你的生态系统中一致且安全的会话管理。了解更多关于注销机制及如何实现注销。
使用 JWT 管理用户权限的实时更改可能也很棘手。由于 JWT 本质上是无状态的,任何更新的权限或角色可能要到令牌过期后才能生效。Logto 提供了有效处理这一问题的策略:
这些解决方案有助于保持权限的更新并确保一个更安全、更响应的系统。了解更多关于管理用户权限变化的实时更改。