假设我有一个典型的Web应用程序CRUD API。我需要通过令牌授权用户,检查用户角色等。
有什么理由让我考虑 JWT 而不是将随机生成的令牌存储在像tokens(token, refresh_token, expiration_date)
这样的表中?
在我看来,JWT 在这里增加了更多的复杂性:
-
用于处理编码/解码的其他代码
-
需要存储 JWT 机密和密钥
-
令牌吊销问题
我必须访问数据库来检查用户角色(尽管我可以将它们包含在有效负载中,但我应该在我的应用程序中检查其他内容(,所以这里没有优势。我在这里可以看到的唯一好处是我可以在不访问数据库的情况下检查令牌过期数据。
同时,将随机生成的令牌存储在数据库中是一个非常简单的解决方案。
我错过了什么吗?
JWT 经常被误解。它们提供的主要好处是无国籍。如果你去你的数据库查询每个请求的权限,那几乎是丢失的,如果不是从理论角度,而是从实践的角度来看。
它们通常不存储在仅http的cookie中,这使得它们容易受到XSS的攻击,但同时允许Javascript客户端读取有效负载(例如,谁登录,他们拥有什么权限等(。不存储在 cookie 中也允许将它们发送到不同的来源,这几乎是它们不应该存储在仅限 http 的 cookie 中的唯一原因(当且仅当您理解并接受这样做的风险时(。
JWT 绝不比普通的旧随机会话令牌更好或更安全 - 在大多数情况下恰恰相反,尤其是经常被忽视的是,与服务器端会话相反,JWT 有效负载是纯文本。它受到消息身份验证的保护,但不受用户查看的保护,这有时可能会成为一个问题。
如果你不需要上面的功能(无状态,从javascript访问(,你不应该有JWT的额外复杂性,你只需要一个普通的旧会话。
您需要考虑的第一件事是谁将生成令牌。 对于 JWT,有效的 OAUTH 提供程序将生成令牌。好处如下:
-
您可以验证令牌的合法性,其中包括以下检查:
A. 受众
B. 到期
C. 签发于
d. 不早于日期
E. 发行人
- 您可以仅根据公钥检查颁发者,这将避免到另一个远程服务器(如数据库(的网络访问。
- 您可以注入任何有效负载,其中可以包含用户信息、电子邮件、角色或任何自定义属性。
- 对于标准 OAUTH JWT,您可以使用通用提供程序(如"Okta"(进行测试。与自定义生成器相反,您必须为用户提供检索此类令牌的机制。
就要检查的代码而言,JWT 非常简单,由"句点"分隔 3 个部分。但是有java和其他语言的库可以为您进行解析 -com.auth0
,特别是jwt
和rsa
,可以让您进行解析和验证。
您的代码将合规且易于移植到其他提供商。