Published on

OAtuh 2.0: 一种授权框架

Authors
  • avatar
    Name
    Joy Peng
    Twitter

What is OAuth?

简单来说,OAuth是一种授权框架,允许第三方应用程序访问用户的资源,而无需用户提供他们的凭据。这是通过授权服务器颁发访问令牌(access token)来实现的。这个访问令牌代表了用户授权第三方应用程序访问他们的资源的许可。

例如,在我的Breaddit项目中,用户可以选择使用谷歌账号登录,这时候Breaddit会请求用户授权,用户同意后,Breaddit会从谷歌授权服务器获取一个token,然后使用这个访问令牌来访问用户的谷歌资源,例如用户的邮箱地址、头像等。

oAuth

如上图,OAuth的工作流程如下:

  • 用户打开第三方应用程序,点击登录按钮。
  • 第三方应用程序将用户重定向到授权服务器。
  • 用户登录授权服务器,授权服务器验证用户身份。
  • 用户同意授权第三方应用程序访问他们的资源。
  • 授权服务器颁发访问令牌给第三方应用程序。
  • 第三方应用程序使用访问令牌访问用户的资源。
  • 用户可以随时撤销对第三方应用程序的访问权限。
  • 访问令牌过期后,第三方应用程序可以使用刷新令牌来获取新的访问令牌。
  • 用户可以随时撤销刷新令牌。

Access Token & Refresh Token

  • Access token是一个短期的令牌,通常在几分钟到几小时之间,用于访问资源服务器。如果第三方应用程序需要访问用户的资源,它必须使用这个访问令牌。如果访问令牌过期,第三方应用程序必须使用刷新令牌(refresh token)。
  • Refresh token是一个长期的令牌,通常在几天到几个月之间,用于获取新的访问令牌。如果访问令牌过期,第三方应用程序可以使用刷新令牌来获取新的访问令牌,而无需用户再次授权。

我们之前介绍过JWTOAuth中的access tokenrefresh token可以使用JWT来实现。 在OAuth中结合JWT有多种好处:

  • Security: JWT是一个安全的方式来传递信息,因为它可以使用签名来验证数据的完整性。
  • Scalability: JWT是无状态的,可以在多个服务之间共享,这使得它非常适合分布式系统。
  • Effeciency: JWT是一个紧凑的格式,可以减少网络传输的数据量。
  • Flexibility: JWT可以存储任何信息,这使得它非常灵活。

Identity Provider vs Authorization Server

OAuth中,有两个重要的概念:Identity ProviderAuthorization Server

  • Identity Provider是一个认证服务,用于验证用户的身份。例如,谷歌、Facebook等。
  • Authorization Server是一个授权服务,用于颁发访问令牌。例如,Auth0、Okta等。

在上面的例子中,谷歌既是Identity Provider,也是Authorization Server。但是在一些情况下,这两个服务可能是分开的,例如,用户可以使用谷歌账号登录,但是访问令牌是由Auth0颁发的。

Auth0是一个第三方的Authorization Server,它可以集成多个Identity Provider,例如谷歌、Facebook、Github等。

OAuth Flows

OAuth有多种授权流程,每种流程适用于不同的场景。下面是一些常见的授权流程:

Authorization Code Flow(授权码模式)

  1. 概述:
  • 授权码模式是 OAuth 2.0 中最常用、最安全的授权模式。

  • 主要用于 服务器端的 Web 应用,因为它涉及到后端服务器与 OAuth 授权服务器之间的交互。

  • 它通过浏览器重定向,首先获取一个 授权码(Authorization Code),然后使用该授权码在服务器端换取 访问令牌(Access Token)。

    2.流程:

  • 用户访问客户端应用,客户端将用户重定向到授权服务器(如 Google、GitHub)以请求授权。

  • 用户同意授权,授权服务器将用户重定向回客户端,同时携带授权码(Authorization Code)。

  • 客户端服务器接收到授权码后,向授权服务器发送请求,使用授权码来交换访问令牌(Access Token)。

  • 授权服务器返回访问令牌,客户端服务器使用该令牌访问资源服务器。

  1. 安全性:
  • 授权码通过浏览器重定向传递给客户端,但访问令牌是在后端通过授权码换取,避免了访问令牌暴露在浏览器中。
  • 适用于需要高安全性的场景,例如 Web 应用、需要持久的用户身份验证等。
  1. 适用场景:
  • Web 应用:有后端服务器,并且需要安全地进行 OAuth 授权。
  • 复杂交互场景:例如,用户需要登录并访问保护资源。

Implicit Flow(简化模式/隐式授权模式)

  1. 概述:
  • 隐式授权模式是在 OAuth 2.0 早期为浏览器中的单页面应用(SPA)设计的。
  • 在此模式下,客户端直接从授权服务器获取 访问令牌,而不是先获得授权码。
  • 因为没有中间的授权码步骤,因此更简单且适用于没有后端服务器的应用。
  1. 流程:
  • 用户被重定向到授权服务器进行身份验证。
  • 用户同意授权后,授权服务器立即将 访问令牌 通过 URL Fragment(哈希值)传递回客户端。
  • 客户端提取访问令牌并使用它访问资源服务器。
  1. 安全性:
  • 由于访问令牌直接暴露在浏览器 URL 中,隐式授权模式的安全性较低,容易受到中间人攻击或令牌泄露。
  • 不推荐在现代应用中使用隐式授权模式,取而代之的是使用更安全的 Authorization Code Flow with PKCE。
  1. 适用场景:
  • 前端单页面应用(SPA):没有后端服务器的情况下,且安全性要求不高的应用。
  • 目前随着 SPA 安全性需求的提升,隐式授权模式的使用逐渐被淘汰。

Resource Owner Password Credentials Flow(密码模式)

  1. 概述:
  • 密码模式 允许客户端直接使用资源所有者(即用户)的用户名和密码来请求访问令牌。
  • 客户端将用户的凭据传递给授权服务器,授权服务器验证凭据后发放访问令牌。
  • 该模式仅在高度信任的场景中使用,因为客户端直接处理用户的敏感信息(用户名和密码)。
  1. 流程:
  • 用户向客户端提供用户名和密码。
  • 客户端将这些凭据发送给授权服务器,请求访问令牌。
  • 授权服务器验证用户的凭据,成功后返回访问令牌。
  • 客户端使用访问令牌请求资源服务器。
  1. 安全性:
  • 因为客户端直接处理用户的用户名和密码,因此存在极高的安全风险。
  • 客户端必须是高度信任的应用,通常仅在 第一方应用 或 非常受信任的第三方应用 中使用。
  1. 适用场景:
  • 受信任的第一方应用:如官方移动应用或桌面应用。
  • 不建议使用,除非其他授权模式无法满足需求,并且客户端高度可信。

Client Credentials Flow(客户端凭据模式)

  1. 概述:
  • 客户端凭据模式适用于 机器对机器(M2M) 的通信场景,其中客户端代表自己,而不是代表用户请求访问令牌。
  • 客户端使用自己的凭据(如 client_id 和 client_secret)直接向授权服务器请求访问令牌。
  1. 流程:
  • 客户端使用自己的凭据(client_id 和 client_secret)向授权服务器请求访问令牌。
  • 授权服务器验证客户端的身份,成功后返回访问令牌。
  • 客户端使用访问令牌请求资源服务器。
  1. 安全性:
  • 只涉及到客户端与授权服务器之间的交互,没有用户参与,安全性取决于客户端的凭据保护。
  • 因为没有用户身份验证的步骤,此模式仅适用于后台服务、API 调用等场景。
  1. 适用场景:
  • 服务器到服务器的通信:后台服务、微服务、API 网关等不涉及用户授权的场景。

OAuth 2.0 vs OAuth 1.0

和OAuth 1.0相比,OAuth 2.0有以下几个优点:

  • 简化了流程:OAuth 2.0的流程更简单,更容易实现。
  • 更安全:OAuth 2.0使用HTTPS来保护数据传输,提供了更好的安全性。
  • 更灵活:OAuth 2.0支持多种授权流程,可以根据不同的场景选择合适的流程。
  • OAuth 2.0支持使用JWT来实现访问令牌和刷新令牌。

References

  1. https://youtu.be/ZDuRmhLSLOY?si=qYzMIHK0NgjNVdV-
  2. https://auth0.com/docs/get-started/identity-fundamentals/authentication-and-authorization