Skip to content

想象一下,你想让你手机上的一个照片编辑应用(我们称之为「美图 App」)使用你存储在云盘服务(比如 Google Photos)里的照片。

你肯定不希望直接把你的云盘用户名和密码告诉「美图 App」,因为这太不安全了。如果「美图 App」被黑了,你的整个云盘账户就都暴露了。

这时候,OAuth 2.0 就派上用场了。它就像一个安全的授权管家。

OAuth 2.0 授权码模式时序图

整个过程是这样的:

  1. 你想授权:你在「美图 App」里点击"从 Google Photos 添加照片"。这时,「美图 App」会把你带到一个由 Google Photos 控制的授权页面。
  2. 应用亮明身份:在这个跳转过程中,「美图 App」会向 Google Photos 服务器表明自己的身份(它会提供一个叫 client_id 的东西,就像是应用的身份证)。
  3. 你同意授权:Google Photos 的授权页面会问你:"「美图 App」 想要访问你的照片,你同意吗?"。你确认同意。需要注意的是,你是在向 Google Photos 而不是「美图 App」输入你的用户名和密码来确认你的身份。
  4. 获得"授权码":你同意后,Google Photos 不会直接给「美图 App」你的密码,而是会给它一个临时的"授权码" (Authorization Code),然后把你跳回到「美图 App」里。
  5. 换取"门禁卡":「美图 App」 在后台用这个"授权码",再加上它自己的"应用身份证"和"应用密钥",悄悄地跟 Google Photos 服务器再联系一次,说:"这是我刚刚拿到的授权码,请给我一个正式的访问凭证"。
  6. 获得"访问令牌":Google Photos 服务器验证无误后,就会发给「美图 App」 一个有时效性的"访问令牌" (Access Token)。这个令牌就像一张限时限权的门禁卡。
  7. 使用门禁卡访问:现在,「美图 App」 就可以拿着这张"门禁卡"去访问你的 Google Photos,读取你的照片了。它在每次请求照片时都会出示这张"门禁卡",Google Photos 服务器看到合法的卡就会放行。

总结一下,OAuth 2.0 的核心思想就是,在不暴露你的密码的前提下,让一个应用(客户端,如「美图 App」)可以得到一个临时的、有特定权限的访问令牌,从而能访问你存储在另一个服务(资源服务器,如 Google Photos)上的受保护资源。 整个授权过程是由专门的授权服务器来管理的,确保了安全。


现在,我们来深入讲解一下 OAuth 2.0 的核心原理。

首先,最关键的一点是:OAuth 2.0 是一个关于"授权"(Authorization)的框架,而不是关于"认证"(Authentication)的协议。它的核心任务是让一个应用程序(客户端)在不获取用户密码的情况下,能够安全地访问用户存储在另一个服务上的资源。它解决的是"授权"问题,即"这个应用被允许做什么",而不是"认证"问题,即"这个用户是谁"。

为了实现这个目标,OAuth 2.0 定义了几个关键角色:

  • 资源所有者 (Resource Owner):就是你,拥有数据的人。
  • 客户端 (Client):想要访问你数据的第三方应用程序,例如前面例子中的「美图 App」。
  • 授权服务器 (Authorization Server):负责验证你的身份并获取你的授权同意,然后颁发"访问令牌"的服务器。例如 Google 的登录和授权页面。
  • 资源服务器 (Resource Server):存储着受保护资源(例如你的照片)并提供 API 接口的服务器。例如 Google Photos 的服务器。

现在,我们来分解一下最常用的一种授权流程——"授权码"模式 (Authorization Code Grant),这正是上文中详细描述的流程。

OAuth 2.0 "授权码"模式原理详解:

这个流程分为两个主要阶段:第一阶段是获取"授权码"(Authorization Code),这个过程发生在用户的浏览器中,是用户能看得到的部分。第二阶段是用"授权码"换取"访问令牌"(Access Token),这个过程发生在应用程序的后端,是用户看不到的。

阶段一:获取授权码 (通过浏览器重定向)

  1. 用户发起授权请求:用户在客户端应用(美图 App)中点击"从Google Photos添加照片"。客户端会构建一个特殊的 URL,将用户的浏览器重定向到授权服务器(Google 的授权页面)。这个 URL 会包含以下关键参数:

    • response_type=code:告诉授权服务器,客户端希望得到一个"授权码"。
    • client_id:客户端的公开标识符,用来告诉授权服务器"我是谁"(例如,我是「美图 App」)。
    • scope:一个或多个权限的字符串,用来声明客户端希望获得哪些权限,例如 read_photosupload_videos。这定义了访问的范围。
    • redirect_uri:一个客户端预先注册好的 URL。当用户授权后,授权服务器会把用户重新导向这个地址。这是一个重要的安全措施,可以防止授权码被泄露给恶意应用。
  2. 用户授权:在授权服务器的页面上,用户需要登录(如果尚未登录),以向授权服务器证明自己的身份。接着,授权服务器会展示一个授权同意页面,明确告知用户:"美图 App 正在请求访问你的照片,你是否同意?"。

  3. 返回授权码:用户点击"同意"后,授权服务器会将用户的浏览器重定向回客户端预先指定的 redirect_uri,并在 URL 中附上一个一次性的、短暂有效的"授权码"。例如:https://client.example.com/callback?code=THIS_IS_THE_CODE

阶段二:交换访问令牌 (通过后端服务器)

  1. 客户端交换令牌:客户端的后端服务器收到了这个带有"授权码"的重定向请求。现在,它需要用这个授权码去换取真正能用来访问资源的"访问令牌"。客户端会向授权服务器的令牌端点 (Token Endpoint) 发送一个 POST 请求,这个请求在后端进行,对用户不可见。请求中包含:

    • grant_type=authorization_code:表明此次请求是使用授权码来换取令牌。
    • code:上一步中收到的授权码。
    • client_id:客户端的标识符。
    • client_secret:客户端的密钥。这个密钥是保密的,只有客户端和授权服务器知道。通过同时提供
    • redirect_uri:必须与第一步中发送的 redirect_uri 完全一致,用于再次校验。

    client_idclient_secret,客户端向授权服务器证明了自己的真实身份,确保授权码没有被中间人截获后冒用。

  2. 颁发访问令牌:授权服务器验证收到的所有信息(授权码是否有效、client_idclient_secret 是否匹配等)。验证通过后,授权服务器会返回一个 JSON 对象,其中包含:

    • access_token:这就是最终的"访问令牌",一个字符串。客户端将用它来访问资源。
    • token_type:通常是 Bearer,表示任何持有此令牌的人都可以用它来访问资源。
    • expires_in:访问令牌的生命周期,单位为秒。
    • refresh_token (可选):一个用于在访问令牌过期后,无需用户再次授权即可获取新访问令牌的令牌。

最终阶段:访问资源

  1. 使用访问令牌:现在,客户端(美图 App)终于拥有了可以访问用户资源的"钥匙"。当它需要从资源服务器(Google Photos API)获取照片时,它会在 HTTP 请求的 Authorization 头中带上这个访问令牌,形式通常是 Authorization: Bearer THE_ACCESS_TOKEN

  2. 资源服务器验证并响应:资源服务器收到请求后,会验证 access_token 的有效性(是否过期、权限是否足够等)。如果一切正常,它就会处理请求并返回客户端所需的数据(例如照片列表)。

通过这套流程,OAuth 2.0 巧妙地将用户身份验证和应用授权分离开,并且全程没有让客户端接触到用户的真实密码,极大地提升了安全性。