Loading

OAuth2.0介绍

为什么

关于OAuth出现的背景, 在上一篇OAuth1.0介绍 中已经写过了, 而2.0的提出必然是为了解决1.0中出现的问题. 感兴趣的可以去看看.

2.0针对1.0的问题提出了解决方案, 将协议升级为HTTPS 同时取消了secret加密签名. 对非 web 应用也进行了支持.

介绍

OAuth是什么呢? 在RFC 文档中是这样介绍的.

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. This specification replaces and obsoletes the OAuth 1.0 protocol described in RFC 5849.

写的比较官方哈, 简单说, 就是授权他人以拥有临时访问资源的权限.

实现

先简单介绍授权过程中涉及到的几个角色:

  • 客户端: 既需要申请资源的应用
  • 资源拥有者: 既用户
  • 授权服务器: 通过此服务器获取权限
  • 资源服务器: 通过此服务器进行资源的操作

授权流程

在授权之前, 客户端需要先到服务器进行备案, 并拿到身份标识:

  • client_id: 用于客户端身份标识
  • client_secret: 用于对请求内容进行签名

整个授权流程如下(截图自 RFC 文档):

image-20220219131441175

其中各个步骤的简单说明:

  1. 客户端向用户申请权限
  2. 用户同意进行授权
  3. 客户端拿着获得的用户授权, 向授权服务器申请权限令牌
  4. 授权服务器通过验证后, 发放权限令牌
  5. 客户端时候令牌, 向资源服务器申请资源
  6. 资源服务器验证通过后, 返回资源

其中的授权服务器和资源服务器只是概念上的拆分, 在实际中可以是同一个服务器(个人感觉这个拆分么的什么用呀).

整个过程使用HTTPS协议进行通信. 其中3-6步, 只是简单的HTTPS请求, 其中比较关键的部分就是用户如何同意授权.

授权模式

1.0版本中, 用户的授权是到资源服务器登录并同意授权后, 再通过回调接口的方式通知客户端成功授权的. 当时存在的问题是对非 web 应用不友好. 而在2.0版本中, 为了应对多种场景, 给出了四种不同的授权模式.

授权码

授权码模式就是客户端先拿到一个授权码, 然后使用授权码到授权服务器获取授权令牌. 与1.0的授权方式差不多.

这里就不用 RFC 文档中的图了, 换一张我画的感觉更简洁一些.

image-20220219144359661

看这个流程, 其实和1.0版本的流程差不多. 对以上几步简单说明.

1. 重定向到服务器授权页面

将用户引导到授权服务器进行授权操作.

携带参数

  • response_type: 请求类型, 值为 code, 标识为授权码模式
  • client_id: 客户端 ID. 用于标识客户端身份
  • redirect_uri: 用户授权成功后, 通知的回调链接.
  • scope: 用于标识需要申请的权限.

2. 用户在 授权服务器完成授权操作

用户在授权服务器页面进行登录授权.

3. 将页面重定向到事先指定的链接, 带上授权 code

用户授权完成后, 授权服务器将页面重定向到第一步中的redirect_uri, 通知客户端授权结果. 在进行跳转时会带上授权成功后的授权码.

4. 使用授权 code 获得令牌 access_token

用户成功授权并拿到授权凭证后, 想授权服务器申请access_token.

携带参数

  • client_id
  • client_secret: 因为当前请求是由后端发起, 不会经过客户端, 因此不会泄露.
  • grant_type: 授权方式. authorization_code(表示授权码)
  • code: 上一步获取的授权码

到这一步, 已经完成整个授权流程.

简化版

有些网站是纯前端的, 没有后端. 这种方式直接向前端颁发授权令牌, 省去了授权码这个步骤.

image-20220219180734672

1. 重定向到服务器授权页面

将用户引导到授权服务器进行授权操作.

携带参数

  • response_type: 请求类型, 值为 token, 表示直接返回token
  • client_id: 客户端 ID. 用于标识客户端身份
  • redirect_uri: 用户授权成功后, 通知的回调链接.
  • scope: 用于标识需要申请的权限.

2. 用户在 授权服务器完成授权操作

用户授权操作没有什么差别.

3. 将页面重定向到回调链接并携带授权 token

因为没有后端服务器, 因此授权成功后直接在重定向链接中带有授权 token. 链接形式: https://test.com/callback#token=ACCESS_TOKEN

注意, 这里access_token是以锚点的形式拼在回调链接上的. 因为浏览器在访问的时候, 不会将锚点发送, 因此可以避免中间人攻击.

以这种方式获取的令牌往往授权时间比较短, 通常就是 session 期间有效.

密码版

这就是原始的版本了, 将你的用户名和密码直接告诉客户端, 然后客户端使用你的密码去申请令牌.

image-20220219200511193

客户端获取 token 时携带的参数如下:

  • grant_type: 授权类型. (password)
  • username
  • password
  • client_id
  • scope

授权服务器校验后会返回授权令牌. 注意, 一般在第一步获取用户名和密码时, 客户端并不对其进行存储, 仅仅是在第二步获取授权时使用.

客户端模式

适用与没有交互界面的应用. 授权过程中没有用户参与, 客户端直接申请 token.

image-20220219200822304

携带参数

  • grant_type: 授权类型(client_credentials)
  • client_id
  • client_secret

授权服务器校验后直接返回access_token. 看这个模式并不是OAuth想要解决的问题啊, 看不懂为什么放在这里

令牌更新

OAuth2.0允许在令牌过期后, 不经过用户进行令牌的更新. 授权服务器在颁发令牌时, 会同时颁发两个令牌: access_token refresh_token.

其中refresh_token的过期时间要更久一些, 用于当access_token过期后对其进行更新.

posted @ 2022-02-19 20:53  烟草的香味  阅读(78)  评论(0编辑  收藏  举报