会话策略
当用户访问您的应用程序时,您希望他们不必每次都登录。在登录一次后,您的应用程序应该保存一些有关用户的数据,并允许他们在下次访问时从上次离开的地方继续。这称为会话。**Auth.js 支持两种主要的会话策略**,即基于 JWT 的会话和数据库会话。
两种会话策略都有优点和缺点,您必须根据应用程序的要求来评估它们。
您可以使用 session.strategy
选项在 Auth.js 的主配置文件中配置会话策略。
JWT 会话
Auth.js 可以使用 JSON Web 令牌 (JWT) 创建会话。这是 Auth.js 的默认会话策略,除非配置了数据库提供程序。当用户登录时,JWT 会被创建 在 HttpOnly
cookie 中。使 cookie 成为 HttpOnly
可防止 JavaScript 从客户端访问它(例如通过 document.cookie
),这使得攻击者更难窃取其值。此外,JWT 使用服务器唯一知道的密钥进行加密。因此,即使攻击者从 cookie 中窃取了 JWT,他们也无法解密它。与短暂的过期时间相结合,这使得 JWT 成为创建会话的安全方法。
当用户注销时,Auth.js 会从 cookie 中删除 JWT,从而销毁会话。
优点
- JWT 作为会话不需要数据库来存储会话;这可能更快、更便宜,并且更容易扩展。
- 此策略需要的资源更少,因为您不需要管理额外的数据库/服务。
- 然后,您可以使用创建的令牌在同一域内的服务和 API 之间传递信息,而无需联系数据库来验证包含的信息。
- 您可以使用 JWT 安全地存储信息,而无需将其暴露给您网站上运行的第三方 JavaScript。
缺点
- 在 JSON Web 令牌的编码过期时间之前将其过期是不可能的 - 这样做需要维护一个无效令牌的服务器端黑名单(至少直到它们真正过期)并在每次呈现令牌时检查每个令牌与黑名单的匹配情况。Auth.js **将** 销毁 cookie,但如果用户在其他地方保存了 JWT,它将保持有效(服务器将接受它),直到它过期。(使用 JSON Web 令牌作为会话令牌时,使用较短的会话过期时间可以使会话更快地失效并简化此问题。)
- Auth.js 启用了高级功能来缓解使用较短的会话过期时间对用户体验带来的负面影响,包括自动会话令牌轮换、可选地发送保持活动消息(会话轮询)以防止短生命周期会话在窗口或标签页打开时过期,后台重新验证以及自动标签/窗口同步,这些同步在会话状态发生变化或窗口或标签页获得或失去焦点时,始终保持跨窗口的会话同步。
- 与数据库会话令牌一样,JSON Web 令牌存储在其中的数据量也有限制。每个 cookie 通常限制约 4096 字节,但确切限制因浏览器而异。您尝试在令牌中存储的数据越多,以及您设置的其他 cookie 越多,您就越接近此限制。Auth.js 实施了会话 cookie 分块,以便超过 4kb 限制的 cookie 将在解析时被拆分并重新组装。但是,由于这些数据需要在每个请求中传输,因此您需要了解使用此技术想要传输多少数据。
- 即使配置正确,也不应该假设存储在加密 JWT 中的信息在任何时候都无法解密 - 例如,由于发现缺陷或技术进步。存储在加密 JSON Web 令牌 (JWE) 中的数据可能会在某些时候受到损害。建议生成一个 密钥,该密钥具有很高的熵。
数据库会话
除了 JWT 会话策略之外,Auth.js 还支持数据库会话。在这种情况下,Auth.js 不会在登录后保存带有用户数据的 JWT,而是会在您的数据库中创建一个会话。然后,会话 ID 会保存在一个 HttpOnly
cookie 中。这类似于 JWT 会话策略,但它只存储一个指向数据库中会话的模糊值,而不是将用户数据保存在 cookie 中。因此,每当您尝试访问用户会话时,您将查询数据库以获取数据。
当用户注销时,会话将从数据库中删除,会话 ID 将从 cookie 中删除。
优点
- 数据库会话可以随时在服务器端进行修改,因此您可以实现使用 JWT 策略等可能更难(但并非不可能)的功能:“注销所有设备”或限制并发登录。
- Auth.js 对您使用的数据库类型没有意见;我们有一个庞大的 官方数据库适配器列表,但您也可以 实现自己的适配器
缺点
- 数据库会话需要往返数据库,因此它们在扩展时可能会变慢,除非您的连接/数据库为此做好准备。
- 许多数据库适配器尚不兼容 Edge,这将允许更快速、更便宜地检索会话。
- 与无状态 JWT 策略相比,设置数据库需要更多工作,并且需要额外的服务来管理。