JWT和OAuth认证之间的主要区别是什么?

590

我有一个新的SPA,使用无状态身份验证模型来使用JWT。常常被要求引用OAuth进行身份验证流程,比如让我发送"Bearer tokens"来代替简单的令牌头,但我认为OAuth比基于简单JWT进行身份验证复杂得多。主要区别是什么?我是否应该使JWT身份验证行为像OAuth?

我还将JWT用作我的XSRF-TOKEN以防止XSRF攻击,但被要求将它们分开?我应该将它们分开吗?任何帮助都将不胜感激,并可能导致一组社区准则。

9个回答

520

TL;DR 如果您只有非常简单的场景,比如一个客户端应用程序、一个API,则可能没有必要使用OAuth 2.0。另一方面,如果有很多不同的客户端(基于浏览器、本机移动设备、服务器端等),那么遵循OAuth 2.0规则可能会使它比尝试自行开发系统更易管理。


正如另一个答案所述,JWT (了解JSON Web Tokens) 只是一种令牌格式。它定义了一种紧凑且自包含的机制,用于以数字签名的方式在各方之间传输数据,并且可以验证和信任。此外,JWT的编码规则也使得在HTTP上下文中非常容易使用这些令牌。

由于JWT是自包含的(实际令牌包含有关给定主题的信息),因此它们也是实现无状态身份验证机制(也称为“无需会话”)的良好选择。当采用此路线时,唯一需要呈现的是访问受保护资源的令牌本身,而所涉及的令牌可以称为承载令牌。

在实践中,您已经可以将其归类为基于承载令牌的身份验证。但是,请注意,您未按照OAuth 2.0相关规范使用承载令牌(请参见RFC 6750)。这意味着依赖授权 HTTP标头并使用承载者身份验证方案。

关于使用JWT防止CSRF攻击:如果不了解确切的细节,则很难确定此实践的有效性。老实说,它似乎不正确或不值得。以下文章(Cookie vs Token:明确指南)可能是有关此主题的有用阅读,特别是“XSS和XSRF保护”部分。

一条最后的建议是,即使您不需要完全采用OAuth 2.0,我强烈建议您在传递访问令牌时使用Authorization头而不是自定义头。如果它们真的是承载令牌,请遵循RFC 6750的规则。如果不是,您始终可以创建自定义身份验证方案并仍然使用该头部。

HTTP代理和服务器会识别并特殊处理授权头,因此,使用这些头将访问令牌发送到资源服务器可降低泄露或意外存储授权请求的概率,尤其是授权头。

(来源:RFC 6819,第5.4.1节

4
这是否意味着如果我在移动应用程序中使用JWT身份验证,就不需要在其POST请求中包含CSRF?与具有表单的Web界面不同? - user805981
4
Cookies vs Tokens: The Definitive Guide是一篇探讨Cookies和Tokens之间差异的文章,但目前链接已无法访问。不过,这篇https://dev59.com/8VoU5IYBdhLWcg3wTVzE也是关于cookie和token用于身份验证的一篇好文。 - Siddharth Jain
4
它们也是实现无状态认证机制的好选择(又称“不需要会话”)。如果你需要一种方式来使令牌失效,因为它可能已经被泄漏、拦截或用户简单地退出登录,但是移除令牌并不安全,因为令牌仍然有效,那么你需要将它们存储在某个数据库中,所以我认为出于安全目的或简单的令牌黑名单,服务器上必须有某种会话概念。你可能会说要使用“刷新”令牌来解决这个问题。但是刷新令牌也可能被拦截,后果更为严重。 - Konrad
3
@Konrad,我实现了一个类似的机制,将未使用的有效令牌存储在表中,并在其过期时从表中释放。对于每个传入的请求,我编写了代码来交叉检查传入的令牌与“未使用的有效令牌”。尽管它可以工作,但我总是有疑虑 - 应该有更好的方法来处理未使用但仍然有效的令牌。 - Venkatesh Laguduva
3
另一方面,刷新令牌会使客户端的实现变得更加复杂。因为如果访问令牌过期了,你需要处理它,如果你只是让用户注销而没有任何手动刷新会话的可能性(比如银行),用户可能会感到不满。这需要付出更多的工作量,而且使用标准的身份验证(OID)和授权(OAuth)方法往往会有些过度。 - Konrad
显示剩余4条评论

492

OAuth 2.0定义了一个协议,即规定了令牌如何传输,而JWT则定义了一个令牌格式。

当客户端向资源服务器呈现令牌时,在(第二个)阶段方面,“JWT身份验证”和OAuth 2.0具有类似的外观:令牌通过标头传递。

但是,“JWT身份验证”不是一个标准,也没有指定客户端如何在第一阶段中获得令牌。这就是OAuth被认为很复杂的原因:它还定义了客户端可以从所谓的授权服务器获取访问令牌的各种方式。

因此,真正的区别在于JWT只是一个令牌格式,而OAuth 2.0是一个协议(可以使用JWT作为令牌格式)。


23
在大多数情况下,OAuth协议实现会使用JWT作为令牌格式吗?如果不是,最常用的是什么? - James Wierzba
33
OAuth中的令牌格式未定义,但JWT应该能够正常使用。 - vikingsteve
3
Bearer Tokens是OAuth 2.0中主要使用的访问令牌类型。Bearer Token是一种不透明字符串,不应该对使用它的客户端有任何含义。有些服务器会发行由十六进制字符组成的短字符串令牌,而另一些服务器则可能使用结构化令牌,如JSON Web Tokens。 - eis
1
对于一个简单的 API 来说,使用授权令牌授予者相同的 API(在用户登录时)存在哪些风险? - variable

206

首先,我们需要区分JWT和OAuth。基本上,JWT是一种令牌格式,OAuth是一种授权协议,可以使用JWT作为令牌。OAuth使用服务器端和客户端存储。如果您想要进行真正的注销,则必须选择OAuth2。使用JWT令牌进行身份验证实际上无法注销,因为您没有身份验证服务器来跟踪令牌。如果您想向第三方客户提供API,则还必须使用OAuth2。OAuth2非常灵活。 JWT实现非常容易且不需要太长时间。如果您的应用程序需要这种灵活性,则应选择OAuth2。但是,如果您不需要此用例场景,则实施OAuth2将是浪费时间。

XSRF令牌始终在每个响应标头中发送给客户端。无论CSRF令牌是否在JWT令牌中发送,都无关紧要,因为CSRF令牌通过其本身进行了保护。因此,在JWT中发送CSRF令牌是不必要的。


31
我不明白为什么这个回答有很多赞,它声称“OAuth是一个认证框架”,这完全是错误的。OAuth是一种授权协议,只是一种授权协议。 - Michael
10
嗨,@Michael,关于这件事情有太多的误解。我编辑了我的评论,谢谢。 - M S
2
你们是在说Oauth只是开发者应该遵循的标准吗?还是它真的是一个框架? - StormTrooper
1
“如果你想要真正的注销,你必须使用OAuth2”——这并不是真的。例如,Devise-JWT是一种非OAuth解决方案,通过使令牌无效来提供“注销”功能:https://github.com/waiting-for-dev/devise-jwt#revocation-strategies - GoBusto
7
@Michael,那不完全正确。RFC的标题是“OAuth 2.0授权框架”,所以我想这也会让人有些困惑;)https://tools.ietf.org/html/rfc6749。不过我明白你的意思。 - hfossli
显示剩余4条评论

138
JWT(JSON Web Tokens)- 它只是一种令牌格式。JWT令牌是JSON编码的数据结构,包含有关发行者、主题(声明)、过期时间等信息。它经过签名以防篡改和验证,并可以使用对称或非对称方法进行加密,以保护令牌信息。JWT比SAML 1.1/2.0更简单,并且受到所有设备的支持,比SWT(Simple Web Token)更强大。
OAuth2 - OAuth2解决了用户希望使用基于浏览器的Web应用程序、本机移动应用程序或桌面应用程序等客户端软件访问数据的问题。OAuth2仅用于授权,客户端软件可以获得授权以代表最终用户访问资源。
OpenID Connect - OpenID Connect在OAuth2的基础上添加了身份验证功能。OpenID Connect对OAuth2添加了一些约束,如UserInfo端点、ID令牌、OpenID Connect提供者的发现和动态注册以及会话管理。JWT是令牌的强制格式。
CSRF保护 - 如果不将令牌存储在浏览器的cookie中,则不需要实现CSRF保护。

12
没有cookie,就没有CSRF保护。如果您没有使用cookie进行授权,则不必担心CSRF保护。 - niranjan_harpale
当我第一次读到“没有CSRF保护”时,我理解为“缺乏CSRF保护”。阅读您接下来的句子使得清楚,您实际上是指“不需要CSRF保护”(或“没有SCRF风险”)。 - at54321

97
所有人似乎都错过了OAUTH的核心问题。
维基百科上说,OAuth是一种开放的授权标准,通常用作互联网用户授权网站或应用程序访问其在其他网站上的信息,但不会透露密码。这个机制被谷歌、脸书、微软和推特等公司使用,以允许用户与第三方应用或网站共享有关其账户的信息。
关键点在于“访问委派”。如果消费者只通过受信任的网站(或应用程序)访问资源(终端点),那么使用OAUTH就没有意义,因为背后有基于id/ pwd的身份验证,还有像OTP这样的多因素认证支持,可以通过JWT来加密访问路径(如OAUTH中的范围)并设置访问过期时间。
只有在以下情况下才能进行OAUTH身份验证:如果你是一个OAUTH提供者,并且资源所有者(用户)希望通过第三方客户端(外部应用程序)访问他们(你)的资源(终端点)。虽然它可以被滥用,但它确实是为同样的目的而创建的。
另一个重要的说明:你自由地使用JWT和OAUTH的“身份验证”一词,但它们都没有提供身份验证机制。是的,一个是令牌机制,另一个是协议,但一旦经过身份验证,它们只用于授权(访问管理)。你必须使用OPENID类型的身份验证或自己的客户端凭据来支持OAUTH。

8
OAuth也可用于自己的客户端,不仅限于第三方。密码凭据授权类型正是如此做的。 - harpratap
7
我在谷歌上寻找这样一个明确的答案,但没有找到。每个人都只是谈论定义,例如代币和协议的区别。你的回答解释了为什么要使用其中之一的真正目的。 非常感谢! - Vivek Goel
1
@harpratap 能做并不意味着我们应该这样做。我认为他在这里提到的重点是,如果您只有可信客户端,则可能不值得实施oauth。是的,您可以为此场景实施oauth,但实施JWT更简单,以实现相同的目的。 - Turbo

17

找出JWT和OAuth之间的主要差异

  1. OAuth 2.0定义了协议,而JWT定义了令牌格式。

  2. OAuth可以使用JWT作为令牌格式或访问令牌(即承载令牌)。

  3. OpenID Connect主要使用JWT作为令牌格式。


10

JWT是一种开放标准,定义了一种紧凑且自包含的安全信息传输方式,用于在两个方(客户端和服务器)之间安全地传输信息。它是一种认证协议,允许编码声明(令牌)在客户端和服务器之间传输,并在客户端身份识别后发出令牌。每次后续请求时,我们发送该令牌。

而OAuth2是一个授权框架,其中有一般程序和设置由框架定义。JWT可以作为OAuth2中的机制来使用。

您可以在此处阅读更多内容

OAuth或JWT?哪一个要使用以及为什么?


3
Jwt是一组严格的指令,用于签发和验证已签名访问令牌。这些令牌包含声明,应用程序使用这些声明来限制对用户的访问。
另一方面,OAuth2不是协议,而是委派授权框架。它是一个非常详细的指南,用于让用户和应用程序在私有和公共环境中授权其他应用程序特定权限。OpenID Connect建立在OAUTH2之上,提供身份验证和授权功能。它详细说明了系统中多个不同角色、用户、服务器端应用程序(如API)以及客户端(如网站或本机移动应用程序)如何相互认证。
需要注意的是,OAuth2可以与Jwt一起使用,实现灵活,可扩展到不同的应用程序。

1
看起来你完全弄反了。 - jbruni

0
  • JWT令牌最多需要在运行时资源服务器和授权服务器之间进行一次通信。资源服务器需要请求授权服务器提供公钥以解密JWT令牌。这可以在资源服务器启动时完成。甚至可以将其存储在资源服务器中的属性文件中,避免了所有查询。

  • OAuth2解决了用户想要使用客户端软件(如基于浏览器的Web应用程序、本机移动应用程序或桌面应用程序)访问数据的问题。OAuth2仅用于授权,客户端软件可以使用访问令牌代表最终用户访问资源。

  • OAuth2可以与JWT令牌或访问令牌(即承载令牌)一起使用。


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