学习笔记 - OAuth 2.0

1. 简介

  1. 快递员的例子:OAuth 2.0 的一个简单解释
  2. OAuth2.0 是目前最流行的授权机制
  3. 用来授权第三方应用(向第三方应用颁发令牌),获取用户数据
  4. 数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据
  5. 系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用

2. OAuth 2.0 的验证方式

  1. 参考文章:OAuth 2.0 的四种方式
  2. 不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份
  3. 然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)

2.1. 授权码(authorization-code)

  1. 第三方应用先申请一个授权码,然后再用该码获取令牌
  2. 是最常用的流程,安全性最高,适用于那些有后端的Web应用
  3. 授权码通过前段传送,令牌是存储在后端,而且所有与资源服务器的通信都在后端完成
  4. 这样前后端分离,可以避免令牌泄露
  5. 流程
    1. A网站请求授权码
    2. B网站返回授权码
    3. A网站在后端请求令牌
    4. B网站返回令牌(向redirect_uri指定的网址,发送一段 JSON 数据)

2.2. 隐藏式(implicit)

  1. 适用于Web应用是纯前端的,必须将令牌储存在前端,即直接向前端办法令牌,没有授权码这个中间步骤
  2. 这种方式把令牌直接传给前端,是很不安全的
  3. 只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效
  4. 流程
    1. A网站请求授权码
    2. B网站返回令牌(将令牌作为URL参数,传给A网站https://a.com/callback#token=ACCESS_TOKEN
    3. 令牌的位置是 URL锚点(fragment),而不是查询字符串(querystring)
    4. 因为 OAuth 2.0 允许跳转网址是 HTTP协议,因此存在"中间人攻击"的风险
    5. 而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险
  5. 锚点介绍参考:URI's fragment

2.3. 密码式(password / resource owner password credentials)

  1. 如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用
  2. 该应用就使用你的密码,申请令牌
  3. 这种方式需要用户给出自己的用户名/密码,显然风险很大
  4. 只适用于其他授权方式都无法采用的情况,且必须是用户高度信任的应用
  5. 流程
    1. 用户提供B网站的用户名密码
    2. A网站带着用户名密码直接向B网站请求令牌
    3. B网站通过身份验证后,直接给令牌(放在JSON数据里,作为HTTP回应)

2.4. 客户端凭证(client credentials)

  1. 适用于没有前端的命令行应用,即在命令行下请求令牌
  2. 这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌
  3. 流程
    1. A应用在命令行向B发送请求
    2. B网站通过验证以后,直接返回令牌

2.5. 令牌使用与更新

  1. 具体做法是在请求的头信息,加上一个Authorization字段,令牌就放在这个字段里面
  2. 令牌到期后,再走一遍申请流程,很可能体验不好,而且没有必要
  3. Oauth 2.0允许用户自动更新令牌,更新方法如下:
    1. B网站颁发令牌的时候,一次性颁发两个令牌
    2. 一个用于获取数据,另一个用于获取新的令牌(refresh token)
    3. 令牌到期前,用户使用 refresh token 发一个请求,去更新令牌
    /oauth/token?grant_type=refresh_token&refresh_token=REFRESH_TOKEN
    

3. GitHub OAuth 第三方登录(授权码模式)

  1. 参考文章:GitHub OAuth 第三方登录示例教程
  2. 其他示例:微信第三方登录(授权码模式)

3.1. 第三方登录原理

  1. A 网站让用户跳转到 GitHub
  2. GitHub 要求用户登录,然后询问 " A 网站要求获得 xx 权限,你是否同意?"
  3. 用户同意,GitHub 就会重定向回 A 网站,同时发回一个授权码
  4. A 网站使用授权码,向 GitHub 请求令牌
  5. GitHub 返回令牌
  6. A 网站使用令牌,向 GitHub 请求用户数据

3.2. 应用登记

  1. 一个应用要求OAuth授权,必须先到对方网站登记,让对方知道是谁在请求
  2. 提交表单以后,GitHub 应该会返回客户端 ID和客户端密钥,这就是应用的身份识别码

3.3. 浏览器跳转Github

  1. 跳转的URL如下
    …/github.com/login/oauth/authorize?client_id=7e015d8ce32370079895&redirect_uri=…/localhost:8080/oauth/redirect
    
  2. 这个 URL 指向 GitHub 的 OAuth 授权网址,带有两个参数
  3. client_id告诉 GitHub 谁在请求
  4. redirect_uri是稍后跳转回来的网址
  5. 用户点击到了 GitHub,GitHub 会要求用户登录,确保是本人在操作

3.4. 授权码

  1. 登录后,GitHub询问用户,该应用在请求授权,是否同意授权
  2. 用户同意授权, GitHub会跳转大到redirect_uri指定的跳转网站,并带上授权码
  3. 跳转回来的URL是下面这个样子
    …/localhost:8080/oauth/redirect?code=859310e7cecc9196f4af
    
  4. 后端收到这个请求以后,就拿到了授权码

3.5. 令牌

  1. 后端使用这个授权码,向Github请求令牌
  2. 作为回应,Github会返回一段JSON数据,里面包含了令牌accessToken

3.6. API数据

  1. 有了令牌之后,就可以向API请求数据了
  2. 请求的时候,必须在HTTP头信息里面打上令牌
    Authorization: token 361507da
    

4. 理解Oauth 2.0

  1. 参考文章:理解OAuth 2.0
  2. OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)
  3. "客户端"不能直接登录"服务提供商",只能登录授权层,以此将用户与客户端区分开来
  4. "客户端"登录授权层所用的令牌(token),与用户的密码不同
  5. 用户在登录的时候,指定授权层令牌的权限范围和有效期
  6. "客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料
  7. 运行流程
    1. 用户打开客户端以后,客户端要求用户给予授权
    2. 用户同意给予客户端授权
    3. 客户端使用上一步获得的授权,向认证服务器申请令牌
    4. 认证服务器对客户端进行认证以后,确认无误,同意发放令牌
    5. 客户端使用令牌,向资源服务器申请获取资源
    6. 资源服务器确认令牌无误,同意向客户端开放资源
  8. 客户端授权模式
    1. 客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证
    2. 严格地说,客户端模式并不属于OAuth框架所要解决的问题
    3. 在这种模式中,用户直接向客户端注册
    4. 客户端以自己的名义要求"服务提供商"提供服务,不存在授权问题

你可能感兴趣的:(学习笔记 - OAuth 2.0)