OAuth 2.0 是目前授权领域的工业级标准协议。它的核心目标是:允许一个应用(客户端)在获得用户同意后,有限度地访问用户在另一个服务(资源服务器)上的资源,而无需共享用户的密码。
简单来说,OAuth 2.0 解决了 “安全授权” 的问题。
一、核心思想与比喻
一个最经典的比喻是 “酒店房卡”:
你(资源所有者) 入住一家酒店(资源服务器),酒店前台(授权服务器)需要验证你的身份(比如用身份证)。
验证通过后,前台给你一张房卡(访问令牌)。这张房卡有特定的权限(只能打开你房间的门,不能开其他房间或进入后台区域),并且通常有有效期(比如住几天)。
你不需要把身份证或房间密码交给任何人。当你需要让清洁人员(第三方客户端)进入房间打扫时,你只需给他这张临时房卡。清洁人员用这张卡开门,完成工作后归还。他既不知道你的身份证,也不知道你的房间密码。
如果房卡丢失或被滥用,你可以向前台报失,使其立即失效(吊销令牌)。
在这个过程中:
密码从未泄露给第三方。
权限是受限的(只能打扫,不能拿你保险箱里的东西)。
授权是可撤销的(可以吊销令牌)。
二、为什么需要 OAuth 2.0?(要解决的问题)
在 OAuth 出现之前,如果有一个第三方应用(比如“云打印服务”)想访问你在 Google 网盘里的照片,通常的做法是:让你直接在“云打印服务”的界面上输入你的 Google 账号和密码。
这种做法存在巨大风险:
密码泄露:第三方应用可以获取你的明文密码,并用它做任何事情(查看邮件、删除文件等)。
权限过大:第三方应用获得了你账号的完全访问权,而不仅仅是它需要的“读取某几张照片”的权限。
难以撤销:如果你想取消该应用的访问,只能修改 Google 密码,这会导致所有使用此密码的其他应用失效。
信任第三方:你必须完全信任这个第三方应用会妥善保管你的密码。
OAuth 2.0 就是为了杜绝上述所有问题而设计的。
三、OAuth 2.0 的核心角色
在 OAuth 2.0 流程中,涉及四个关键角色:
资源所有者 (Resource Owner): 拥有受保护资源(如照片、联系人)的用户。也就是“你”。
客户端 (Client): 想要访问用户资源的第三方应用。例如,那个“云打印服务”。
资源服务器 (Resource Server): 托管用户受保护资源的服务器。例如,Google 的网盘服务器,存储着你的照片。
授权服务器 (Authorization Server): 在验证用户身份并获取其同意后,向客户端颁发访问令牌的服务器。通常,授权服务器和资源服务器由同一家公司运营(如 Google),但在概念上是独立的。
四、核心概念
访问令牌 (Access Token):
一个字符串,代表授予客户端的访问权限。
客户端在访问资源服务器时,必须出示此令牌。
令牌有作用域(Scope) 和有效期。例如,一个令牌的作用域可能是
read:photos,有效期是1小时。
刷新令牌 (Refresh Token):
一个用于获取新的访问令牌的凭证。
当访问令牌过期后,客户端可以使用刷新令牌向授权服务器申请一个新的访问令牌(无需用户再次参与)。
刷新令牌通常有效期更长,且需要被客户端安全存储。
授权许可 (Authorization Grant):
客户端获取访问令牌的“凭证”或“方法”。OAuth 2.0 定义了四种主要类型,对应不同场景。
授权码 (Authorization Code):
一种特殊的、短命的授权许可。它是 OAuth 最常用、最安全流程(授权码流程)中的核心中间产物。
五、OAuth 2.0 的四种授权流程(授权许可类型)
OAuth 2.0 根据客户端类型和场景,定义了四种获取令牌的流程:
1. 授权码流程 (Authorization Code Flow)
最适合: 有后端的 Web 应用(最常用、最安全的流程)。
步骤:
用户点击客户端应用的“使用 Google 登录”按钮。
客户端将用户重定向到授权服务器(Google),并携带自己的ID、回调地址和所需权限(Scope)。
用户在授权服务器上登录并确认授权(“允许此应用访问你的基本信息吗?”)。
授权服务器将用户重定向回客户端提供的回调地址,并在URL中附上一个授权码。
客户端(后端)用这个授权码,加上自己的客户端密钥,向授权服务器请求访问令牌。
授权服务器验证授权码和客户端密钥,返回访问令牌(和可选的刷新令牌)。
关键点: 令牌不会暴露给用户浏览器,安全性最高。
2. 隐式流程 (Implicit Flow)
最适合: 纯前端单页应用,没有后端。
步骤简化版: 与授权码流程类似,但在第4步,授权服务器直接将访问令牌附在重定向URL的片段中返回给浏览器。不返回刷新令牌。
关键点: 令牌暴露在浏览器URL中,安全性较低。现代实践中已被 PKCE 增强的授权码流程所取代。
3. 密码凭证流程 (Resource Owner Password Credentials Flow)
场景: 用户高度信任的客户端(例如,同一个公司开发的手机App和其服务器)。
步骤: 用户直接将用户名和密码交给客户端,客户端用这些信息直接向授权服务器请求令牌。
关键点: 仅在万不得已时使用,因为它仍然需要用户提供密码给客户端,违反了OAuth的核心理念。
4. 客户端凭证流程 (Client Credentials Flow)
场景: 客户端访问其自己拥有的资源,或与用户无关的后端API。
步骤: 客户端使用自己的客户端ID和密钥,直接向授权服务器请求一个访问令牌。
关键点: 这是一种服务器对服务器的认证,不涉及用户授权。
六、一个完整的授权码流程示例(以“云打印服务”访问 Google 照片为例)
用户发起请求: 你在“云打印服务”网站点击“导入 Google 照片”。
重定向到授权服务器: 云打印服务将你的浏览器重定向到 Google 授权服务器的地址,并携带参数:
client_id=云打印的ID,redirect_uri=云打印的回调地址,scope=read photos,response_type=code。用户认证与授权: 如果你未登录 Google,会先登录。然后 Google 会显示一个同意页面:“云打印服务请求访问你的 Google 照片。允许吗?”
返回授权码: 你点击“允许”。Google 将你的浏览器重定向回
redirect_uri,并在 URL 后附加?code=AUTH_CODE_HERE。交换令牌: 云打印服务的后端服务器收到这个授权码,然后秘密地向 Google 令牌端点发送请求,包含:
code=AUTH_CODE_HERE,client_id,client_secret,redirect_uri。颁发令牌: Google 验证所有信息无误后,返回一个 JSON 响应:
{“access_token": “ACCESS_TOKEN_HERE", “expires_in": 3600, “refresh_token": “REFRESH_TOKEN_HERE”}。访问资源: 云打印服务现在可以用这个
access_token访问 Google 照片 API,例如:GET https://photos.googleapis.com/v1/photos?access_token=ACCESS_TOKEN_HERE。刷新令牌(可选): 一小时后
access_token过期,云打印服务可以使用refresh_token向 Google 请求一个新的access_token,无需你再次授权。
七、OAuth 2.0 与 OpenID Connect
常与 OAuth 2.0 混淆的是 OpenID Connect。
OAuth 2.0 是关于 授权 的协议。 它回答:“这个应用是否有权限访问 X?”
OpenID Connect 是基于 OAuth 2.0 的 认证 协议。 它在 OAuth 流程之上增加了一个标准化身份层,回答:“用户是谁?”(它会返回一个叫
id_token的 JWT,其中包含用户身份信息如姓名、头像等)。 我们常说的“第三方登录”(如“使用 Google 账号登录”),其底层技术就是 OAuth 2.0(用于授权访问基本信息) + OpenID Connect(用于告知身份)。
总结
OAuth 2.0 是一个精巧的授权框架,它通过引入令牌机制,将资源所有者的身份凭证(密码)与对第三方应用的授权分离,从而实现了更安全、更可控的资源访问代理。 它不仅是“第三方登录”的基石,也是现代微服务架构和API经济中服务间安全通信的关键组件。理解其角色、流程和概念,对于任何从事互联网开发的工程师都至关重要。
评论区