OAuth2.0

本贴最后更新于 1062 天前,其中的信息可能已经时移俗易

OAuth2.0

本文总结一些互联网上已有的简单明了的介绍了该协议的内容,详细理解建议把参考的文章都阅读以下,我只是摘取了一些主要的部分,帮助自己理解.

参考:

简介

一个授权机制(协议),用于给第三方应用授权,来获取用户数据.为了让第三方获取这些数据,会授予第三方一个短期有效的令牌(Token),用来代替账号密码. 是 Open Authorization 的简写.

  • 与账号密码的不同点
    • 短期有效
    • 可以被撤回
    • 有权限范围,即签发人员可以限定该 Token 拥有者的权限

具体关于 OAuth2.0 的内容可以参见==RFC 6749==

OAuth2.0 四种方式

这四种方式分别为:

  • 授权码 Authorization Code
  • 隐藏式
  • 密码式
  • 客户端凭证

不管采用哪一种方式,都必须要得到系统的备案,说明身份,然后拿到两个身份识别码

  • 客户端 ID ClientID
  • 客户端密匙 Client Secret

备案是为了方式令牌为滥用,没有备案过的第三方应用是不会拿到令牌的.

注意:是第三方应用来获取用户信息

方式一:授权码 Authorization Code

第三方应用申请一个授权码,然后通过该授权码获取令牌

令牌是存储在后端的,所有的与资源服务器的通信都是在后端完成的,这样的前后端分离,可以避免令牌的泄露.

sequenceDiagram autonumber a.com->>+b.com: 请求授权码 b.com-->>-a.com: 返回授权码 a.com->>+b.com: 请求令牌Token b.com-->>-a.com: 返回令牌Token

过程一:如果将一个用户在 B 网站的数据,授权给 A 网站使用.类似于在 a.com 点击通过第三方登录,向 b.com 发送请求.

请求内容包括

response_type=code&         //要求返回授权码
client_id=CLIENT_ID&        // 让b知道是谁在请求
redirect_uri=CALLBACK_URL&   //b接受或拒绝请求后的转跳地址
scope=read                    // 要求的数据授权范围

过程二:用户转跳后,会要求用户登录,然后询问是否同意给 A 网站授权,如果用户同意,此时 B 就会转跳到 redirect_url 指定的网址.转跳的同时,会返回一个授权码.

第三步:拿到该授权码后,网站 b 就会在后端向 b 网址请求令牌(即这些操作都是在后台直接进行的,对用户不可见)

client_id=CLIENT_ID&    //用于确认身份
client_secret=CLIENT_SECRET&    //用于确认身份
grant_type=authorization_code&    //表明采用的授权方式
code=AUTHORIZATION_CODE&    //上一步拿到的授权码
redirect_uri=CALLBACK_URL    //令牌颁发后的回调网址

步骤四:向上一步的 redirect_rul 发送一个 JSON 数据,其中的 access_token 字段就是令牌

{  
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{...}
}

方式二: 隐藏式

针对一些纯前端应用,没有后端.这种方式允许前端直接颁发令牌,没有授权码这个步骤,因此被称为隐藏式.

sequenceDiagram autonumber a.com->>+b.com: 请求令牌Token b.com-->>-a.com: 返回令牌Token

方式三:密码式

如果你高度信任某个应用,可以直接将你的账号密码告诉该应用,该应用就会通过你的账号密码来申请令牌 Token.

sequenceDiagram autonumber a.com->>+b.com: 申请获取账号密码 b.com-->>-a.com: 返回账号密码 a.com->>+b.com: 通过账号密码请求令牌Token b.com-->>-a.com: 返回令牌Token

方式四:凭证式

适用于没有前端的命令行应用,即在命令行中请求令牌.

这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

令牌的使用

得到 Token 后,A 网站就可以直接向 B 网站的 API 发送请求,获取数据了.

此时,每个发到 API 的请求,都必须带有令牌。具体做法是在请求的头信息,加上一个 Authorization 字段,令牌就放在这个字段里面。

更新令牌

B 网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。

  grant_type=refresh_token&    //表示要求更新令牌
  client_id=CLIENT_ID&        //确认身份
  client_secret=CLIENT_SECRET&    //确认身份
  refresh_token=REFRESH_TOKEN        //之前颁发的refresh_token

AccessToken 的具体用法

OAuth 2.0 通过补充规范 RFC 6750 示范了一种 access token 的具体用法,符合这种具体用法的 access token 统称为 Bearer token。注意:Bearer token 不是一种 token 值的格式,而是一种规范的用法,OAuth 2.0 没有规定 token 值的内容、格式.

传递给服务器的方式

OAuth 2.0 在补充规范 RFC 6750 中定义了三种传递 access token 的方式。

  1. 放在请求头中传递:在请求头 Authorization 字段中使用 Bearer 这一关键字传递。资源服务器必须支持这种传递方式。
GET https://api.amazon.com/user/profile
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
  1. 放在表单请求体中传递:资源服务器自行选择是否支持这种传递方式。
POST https://api.amazon.com/user/profile
Content-Type: application/x-www-form-urlencoded

access_token=2YotnFZFEjr1zCsicMWpAA
  1. 放在 URI 的查询参数中传递(不建议):RFC 6750 不建议采用这种方式,如果实在无法使用前两种方式,再来考虑这种。资源服务器自行选择是否支持这种传递方式。

accessToken 的值

OAuth 2.0 没有规定 access token 值的内容、格式,只要求 access token 对客户机应用不透明。实操中常见的格式分为两类:

  1. 读库令牌:access token 值是一个随机生成的标识符,在数据库中存储有效期,谁颁发的,颁发给谁的,权限范围等元数据信息。校验时需先读库,优点是当授权服务器想主动撤销已签发的 access token 时非常方便。
  2. 自包含令牌**(例如 JWT)**:access token 值是把上述元数据信息编码、签名、加密后得到的值,优点是校验时无需读库,缺点是当授权服务器想主动撤销已签发的 access token 时会比较棘手。

JWT

JSON WEB TOKEN 是目前比较流行的自包含令牌格式.

  • 基于 json 的通用性,可以跨语言支持。
  • 简单紧凑,字节占用小,能够放在 HTTP 报头或 URI 的查询参数中进行传输。
  • 自包含并提供防篡改机制。

相关的标准文件 :
【RFC7519】JSON Web Token (JWT)

【RFC7515】JSON Web Signature (JWS)

【RFC7516】JSON Web Encryption (JWE)

【RFC7517】JSON Web Key (JWK)

【RFC7518】JSON Web Algorithms (JWA)

服务器校验 AccessToken

【RFC 7662】OAuth 2.0 Token Introspection

OAuth 2.0 没有规定资源服务器如何校验 access token,只是说资源服务器与授权服务器之间自己协调。实操中一般采用以下方法校验:

对于小型 Web 应用:资源服务器通常与授权服务器同为一体,自然能够通过读库来校验。

对于大型 Web 应用:授权服务器和资源服务器通常是独立部署的,有三种方式校验:

  1. 使用读库令牌作为 access token,在数据库存储层面做共享,使得资源服务器能够通过读库来校验。
  2. 使用读库令牌作为 access token,由授权服务器提供一个令牌校验接口,资源服务器请求该接口来校验。OAuth2.0 在补充规范 RFC 7662 中定义了令牌校验接口(Introspection Endpoint)的相关标准。
  3. 使用自包含令牌作为 access token,资源服务器和授权服务器双方约定好自包含令牌的结构、签名密钥、加密方法,资源服务器按照约定规则自行校验。

撤销 Token

补充规范标准文件【RFC 7009】OAuth 2.0 Token Revocation

OAuth 2.0 在补充规范 RFC 7009 中定义了一个由授权服务器提供的撤销接口(Revocation Endpoint)来供客户机应用申请撤销 access_token 或 refresh_token。

当用户在客户机应用退出登录、更换账号、注销账号,或卸载了客户机应用时,客户机应用需要通知授权服务器自己不再需要该用户的令牌,授权服务器将清除与该令牌相关的授权信息。 这样可以防止被遗弃令牌的滥用,并改善用户体验,因为失效的授权将不再出现在授权服务器展示给用户的已授权客户机应用列表中。

其他

回调地址

即下一步要转跳或者发送请求的地址

一个向 Github 发送请求的实例

GitHub OAuth 第三方登录示例教程 - 阮一峰的网络日志 (ruanyifeng.com)

  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 8 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 18 关注

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...