我需要在哪里使用 JWT?
Posted
技术标签:
【中文标题】我需要在哪里使用 JWT?【英文标题】:Where do I need to use JWT? 【发布时间】:2015-10-19 15:59:22 【问题描述】:除了structure and protocol,我想知道 JWT 在哪里适合客户端/服务器通信?
这里是用来代替身份验证和会话 cookie 的吗? 这是为了减轻服务器在数据库或内存中存储会话令牌的负担吗? 客户端是否需要确保他们从预期的服务器接收数据,如果这不是问题,我就不需要 JWT? 当连接是 HTTPS/SSL 时,服务器到服务器的通信是必要的还是好的做法?【问题讨论】:
【参考方案1】:JWT 到底是什么?
它是一个只有服务器才能生成的令牌,并且可以包含数据的有效负载。
这有什么意义?
JWT 有效负载可以包含用户 ID 等内容,这样当客户端向您发送 JWT 时,您可以确保它是由您发出的,并且您可以查看它发给谁已发布。
它在哪里有用?
通常,在RESTful APIs, 中,服务器不得使用任何类型的会话。
它与使用会话有何不同?
在典型的会话流程中,浏览器会发送一个包含令牌的 cookie,该令牌然后在服务器上匹配到服务器使用的一些数据 对用户进行身份验证。
在 JWT 流中,令牌本身包含数据。服务器解码令牌以仅对用户进行身份验证。服务器上不存储任何数据。
什么是使用 JWT 的典型身份验证流程?
用户凭据发送到/signin
/signin
返回一个 JWT(用密钥签名)
JWT 存储在localStorage
JWT 在每个请求上发送(到 API)
服务器可以读取 JWT 并从中提取用户 ID
Jwt 包含 algorithm.data.signature 的编码形式,因此如果用户试图修改用户 ID 或 jwt 中保存的任何其他数据,则 jwt 签名将失效。
Jwt 被编码(未加密),因此任何人都可以读取 jwt 的数据组件(例如,参见 jwt.io)。因此,建议不要在 jwt 中存储密码等任何机密。
还建议在发出包含 jwt 的 Web 请求时使用加密连接 (SSL/TLS),否则攻击者可以窃取 jwt 并使用它来冒充您。
【讨论】:
我听过的最好的答案之一。 真的吗?您是否将令牌存储在本地存储中? cheatsheetseries.owasp.org/cheatsheets/… @MohsenKashi XSS 攻击基本上是在您的网站内运行外国 JS 时。在这种情况下,XSS 脚本获得与您自己的脚本相同的权限;因此,无论是存储在 cookie、LocalStorage、SessionStorage、IndexedDB 还是其他任何东西中,都可能被盗。在保护网站的同时还容易受到 XSS 的攻击几乎是不可能的。 @OverCoder 带有httpOnly
标志的 Cookie 无法通过客户端脚本访问,因此不易受到 XSS 攻击。【参考方案2】:
JWT 只是一种流行的基于 JSON 格式的安全令牌。
JWT 令牌并不是为了替换会话 cookie 而发明的。它们主要用于保护 Web API(请求数据)。另一方面,会话 cookie 用于 Web 应用程序,您可以在其中登录用户并随每个请求(请求页面)自动发送 cookie。
JWT 令牌包含在 Authorization HTTP 标头中,作为不记名身份验证方案的一部分。使用不记名方案身份验证的主要优点是它不易受到CSRF 攻击,因为您的脚本需要将令牌显式附加到请求并且可以跨域使用(与 cookie 不同)。
承载方案身份验证确实需要 HTTPS 连接,因为任何设法窃取令牌的人都可以使用它来访问 API,只要令牌有效。
OAuth2 等安全协议使用 JWT 令牌来保护 API。 OpenID Connect 使用 JWT 令牌来验证 Web 应用程序,但将令牌存储在 cookie 中。
由于 JWT 令牌由颁发者(进行身份验证的服务器)进行数字签名,因此无需再次与服务器对话即可对其进行验证。数字签名允许您使用私钥对一段数据(在这种情况下为 JWT 令牌)进行签名,并且接收令牌的服务器只需要公钥来验证没有任何数据被更改。所以 API 服务器只需要来自授权服务器的公钥(不是秘密的)来信任它发布的令牌。 API 的客户端带来令牌,API 服务器无需与授权服务器对话即可对其进行验证。
【讨论】:
【参考方案3】:当发行者(生成 JWT)和接收者(验证 JWT)属于不同的自治方时,IMO JWT 最有用。虽然可以,但是不需要将 authentication/session-cookie/token-storage/etc 替换为 JWT。
【讨论】:
以上是关于我需要在哪里使用 JWT?的主要内容,如果未能解决你的问题,请参考以下文章
JWT 吊销信息在哪里存储,mongoDB 还是 Redis?