JWT(JSON Web Tokens)和Bearer Token之间有什么区别?

240
我正在学习关于授权的内容,比如基本授权、摘要授权、OAuth2.0、JWT和Bearer Token。JWT被用作OAuth2.0标准中的访问令牌。JWT的相关信息可以在RFC 7519中找到,而Bearer Token的相关信息可以在RFC 6750中找到。
举个例子,Bearer Token:
Authorization: Bearer <token>

我过去通常通过AJAX发送令牌到服务器,或者将令牌添加到URL的查询字符串中。我知道令牌也可以通过将其添加到请求头中来发送。这是否意味着令牌应该添加到Authorization Bearer头部?
JWT和Bearer令牌之间有什么关系?

相关问答(在下面的一个答案中提到):OAuth 2中的Bearer令牌和token_type是什么? - undefined
5个回答

316

简短回答

JWT是一种方便的方法,用于编码和验证声明

Bearer Token只是一个字符串,可能是任意的,用于授权。

背景(故事时间)

几年前,在JWT革命之前,<token>只是一个没有固有含义的字符串,例如2pWS6RQmdZpE0TQ93X。然后在数据库中查找该令牌,其中保存了该令牌的声明。这种方法的缺点是每次使用令牌时都需要访问DB(或缓存)。

JWT通过编码和验证自己的声明(通过签名)来实现。这使得人们可以发行短暂的JWT,这些JWT是无状态的(即:自包含的,不依赖于任何其他服务)。它们不需要访问DB。这减少了DB负载并简化了应用程序架构,因为只有发行JWT的服务需要担心访问DB/持久性层(您可能遇到的refresh_token)。


谢谢,那么关于 Mac 授权,Mac 和 Bearer 是一样的吗? - laoqiren
1
最佳答案在其他地方,例如:https://dzone.com/articles/oauth-20-bearer-token-profile - rmharrison
先生,多年以后我请求您的原谅,但是什么秘钥?如果秘钥只有一个,那还好。但如果我们与一些公司共享API,每个公司都有不同的秘钥,我们该怎么办?我们应该将秘钥存储在数据库中吗?如果是这样的话,数据库关系依然存在,是吗? - Soner from The Ottoman Empire

199

JWT是一种编码标准,用于包含可签名和加密的JSON数据负载的令牌。

JWT可以用于许多事情,其中之一就是承载令牌,即您可以向某些服务呈现的信息,通过您拥有它(作为"承载者")来授予您访问权限。

承载令牌可以以不同的方式包含在HTTP请求中,其中一种(可能是首选)是Authorization头。但您也可以将其放入请求参数、cookie或请求正文中。这主要取决于您和您尝试访问的服务器之间的关系。


那么如何解析Authorization头中的令牌,因为有一个Bearer,我需要使用 String.slice() 函数,是否有任何中间件来解析它? - laoqiren
我正在使用Node.js。 - laoqiren
如果您想要一个最小的解析器,请使用auth-header包。 - Demurgos
1
或者直接使用 String.slice() :) - Paul Siersma
先生,请原谅我几年后问这个问题,那么秘钥是什么?如果只有一个秘钥,那就没问题了。但如果我们与一些公司分享我们的API,并为每个公司提供不同的秘钥,该怎么办?我们应该把秘钥存储在数据库中吗?如果是这样,数据库关系仍然存在,不是吗? - Soner from The Ottoman Empire
使用 string.split(" ") - Kishore

2
请求中的Authorization头部的值包含一个可以被服务器用来授权请求的值。
该头部的格式如下:
Authorization: <auth-scheme> <authorization-parameters>

认证模式告诉我们设置参数的值的类型。
定义了几种模式,以下是一些示例:
- 基本模式 - Bearer模式 - Digest模式
这里有一个更完整的列表here
所以Bearer是一种认证模式。
Bearer令牌可以有不同的格式。JWT是一种令牌格式,另一种令牌格式称为不透明令牌。
JWT是一个Base64编码的Json格式字符串,包含头部、主体和签名部分。在这种类型的令牌中,您可以添加不同的声明,这些声明声称某些事情(如用户名、电子邮件地址、角色等)。
而不透明令牌只是一个随机的唯一字符串,它是不透明的,不包含任何附加信息。
JWT令牌和不透明令牌是不同的Bearer令牌格式。
如何使用它们以及何时使用每个都是一个很大的讨论话题;有好的和坏的用法。但是这两者通常在实现oauth2时使用,但还有其他几种用户情况。
我曾经看到JWT被发送到请求体中只是为了发送签名数据。所以说实话,JWT只是一种某些数据的格式。它不一定需要是一个令牌。

0

既然您提到在URL查询参数中发送令牌,这可能对您很有用。我认为像您和其他一些答案提到的将它们作为URL参数发送可能会导致一些安全问题。您应该始终在HTTP请求中使用身份验证标头,如以下RFC文档中推荐的那样。 :) RFC6749 使用访问令牌

据我所知,Bearer只是令牌的更通用术语,因为在RFC7523中,它也经常被称为JWT Bearer Token。然而,与“普通”的Bearer Token相比,JWT还以JSON格式保存信息(关于发行人、创建日期等)。请注意,这些参数可以被任何人解码,因此不应包含敏感数据,除非加密。JWT只是确保发送到令牌内部的数据没有被篡改,因为签名由HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)组成,其中secret可以是密码短语或公钥/私钥对。对于使用私钥签名的令牌,它还可以验证JWT的发送者是否是其所说的人。JWT的有效载荷大小不应超过约8kB,因为某些浏览器不接受此大小的令牌。有关JWT的更多信息,您可以查看JWT.io或更详细的信息RFC 7523 JWT for oAuth

更新: 我从RFC中收集到的其他信息证实了我的假设,这个话题非常有趣:

Clients using the URI Query Parameter method SHOULD also send a
   Cache-Control header containing the "no-store" option.  Server
   success (2XX status) responses to these requests SHOULD contain a
   Cache-Control header with the "private" option.

   Because of the security weaknesses associated with the URI method
   (see Section 5), including the high likelihood that the URL
   containing the access token will be logged, it SHOULD NOT be used
   unless it is impossible to transport the access token in the
   "Authorization" request header field or the HTTP request entity-body.
   Resource servers MAY support this method. https://www.rfc-editor.org/rfc/rfc6750#section-2.3


   Bearer Token
      A security token with the property that any party in possession of
      the token (a "bearer") can use the token in any way that any other
      party in possession of it can.  Using a bearer token does not
      require a bearer to prove possession of cryptographic key material
      (proof-of-possession). https://www.rfc-editor.org/rfc/rfc6750#section-1.2

-9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接