前言
OAuth2.0 是目前互联网上比较流行的授权方式,GitHub、掘金等大部分网站都采用 OAuth 的方式支持第三方账号登陆。之前工作中有接触到但是没有深入的去了解其中的机制,这里根据原理做了一个小的 demo,源码地址:OAuth2-demo
官方文档
OAuth2.0 标准出自 RFC6749 The OAuth 2.0 Authorization Framework,英文文档,有兴趣的可以研读一下。
使用场景
比如我们遇到了一个错误,在 必应 上搜索了一下,出现的第一个结果来自 CSDN,点进去读了几行网站弹出登陆页面,登陆框底部就有“其他登陆方式”的选项,可以使用 QQ、微博、百度、GitHub、开放原子开源基金会等账号登陆,这样可以不用在将密码提供给 CSDN 的情况下,授权 CSDN 访问第三方网站上的用户名等一些受密码保护的信息。
角色
授权流程中几个角色:
- 资源所有者:就是用户自己
- 客户端:即当前使用的网站和程序
- 认证服务器:存放受保护的数据的网站提供的身份认证
- 资源服务器:存放受保护的数据的网站
授权方式
OAuth2.0 定义了 4 种授权方式,各种方式之间部分流程略有不同。
- 授权码模式
- 简化模式(相较于授权模式少了一步获取授权码的流程)
- 密码模式(直接将密码提供给客户端,一般不用)
- 客户端模式
授权码模式是最流程最严密的模式,用得应该是最多的。
授权流程
以授权码模式为例:
sequenceDiagram
客户端->>资源所有者: 请求授权
资源所有者-->客户端: 同意授权
客户端->>认证服务器: 1️⃣ 请求授权码
认证服务器-->客户端: 2️⃣ 授权码
客户端->>认证服务器: 3️⃣ 使用授权码请求 token
认证服务器-->客户端: 4️⃣ token
客户端->>资源服务器: 5️⃣ 访问被保护的资源
资源服务器-->客户端: 6️⃣ 被保护的资源
为了简化流程,demo 中省略了一个资源服务器。假设客户端运行在 http://localhost:8001/client,认证服务端运行在 http://localhost:8000/auth-server,每一步具体操作如下:
请求授权码
请求地址
参数解释
参数 | 含义 |
---|---|
response_type | 授权类型为授权码模式 |
client_id | 客户端 id |
redirect_uri | 服务端返回授权码时的重定向地址 |
scope | 授权范围 |
state | 客户端状态,自定义值 |
认证服务器重定向至登陆
认证服务器重定向至本站登陆页面使用账号密码进行认证。
认证服务器返回授权码
认证服务器登陆成功后给客户端返回授权码。
请求地址
http://localhost:8001/client/index?code=XXX&state=YYYY
参数解释
参数 | 解释 |
---|---|
code | 认证服务器生成的授权码 |
state | 客户端请求授权码时发过去的客户端状态,原值返回,作用不明 |
客户端使用授权码请求 token
请求地址
参数解释
参数 | 解释 |
---|---|
code | 认证服务器返回的授权码,只能使用一次 |
认证服务器返回 token
参数
参数 | 含义 |
---|---|
access_token | token |
token_type | token 类型 |
expires_in | 多久后过期,秒为单位 |
refresh_token | 刷新令牌 |
scope | 授权范围 |
客户端使用 token 请求资源
客户端获取到 token 之后就拿着 token 向资源服务器访问对应的资源了。
请求地址
http://localhost:8000/auth-server/userInfo?accessToken=XXX