首页 > 解决方案 > URI 中的 JWT 是一种不好的做法吗?

问题描述

我有一个存储在 Redis 中的令牌 (JWT) 后备列表,并希望我的网站的用户能够以 RESTful 方式将他们的令牌列入黑名单。

我可以:

  1. /sessions/<token>使用 DELETE 方法构建路由
  2. /sessions/使用 DELETE 方法和请求正文中发送的令牌构建路由。

第一个解决方案很简单,但令牌存储在服务器的日志和用户浏览器的历史记录中。

第二种解决方案似乎更好,但我不确定我是否通过发送带有正文的 DELETE 请求来破坏 HTTP RFC 的幂等性原则。

在这种情况下,最佳做法是什么?

标签: httpjwt

解决方案


URI 中的 JWT 是一种不好的做法吗?

JWT 令牌在语法方面是 URL 安全的。来自RFC 7519

JWT 表示为由句点 ( .) 字符分隔的 URL 安全部分序列。每个部分都包含一个 base64url 编码的值。[...]

但是,当使用 JWT 作为不记名令牌时,建议避免在 URL 中发送它们。请参阅RFC 6750中的以下引用:

不要在页面 URL 中传递不记名令牌:不应该在页面 URL 中传递不记名令牌(例如,作为查询字符串参数)。

相反,不记名令牌应该在采取保密措施的 HTTP 消息头或消息体中传递。

浏览器、Web 服务器和其他软件可能无法充分保护浏览器历史记录、Web 服务器日志和其他数据结构中的 URL。如果不记名令牌在页面 URL 中传递,攻击者可能能够从历史数据、日志或其他不安全的位置窃取它们。


对于您问题中提到的情况,您可能不需要发送完整的令牌。您可以为令牌提供唯一标识符(存储在jti声明中),然后仅将令牌标识符发送到服务器。

jti请参阅上述 RFC 中如何定义声明:

4.1.7. “jti”(JWT ID)声明

( jtiJWT ID) 声明为 JWT 提供唯一标识符。标识符值的分配方式必须确保相同的值被意外分配给不同的数据对象的可能性可以忽略不计;如果应用程序使用多个发行者,则必须防止不同发行者产生的值之间的冲突。该jti声明可用于防止 JWT 被重放。该jti值是区分大小写的字符串。使用此声明是可选的。

UUID应该足够唯一以识别您的令牌而不会发生冲突。

您也不需要将完整的令牌存储在黑名单中:仅存储jti声明的值和您可能认为相关的一些其他声明(例如subexp)。


DELETE请求不应包含正文。所以你可以使用,你的令牌的唯一标识符DELETE /sessions/{id}在哪里。{id}


推荐阅读