先看流程图
- OAuth2.0是个工业级别的授权协议
- 授权第三方APP
- user Agent:浏览器或者App
角色和流程
- 资源所有者 (resource owner)
- 客户端、第三方应用 (client)
- 资源服务器 (resource server)
- 授权服务器 (Authorization server)
A. 请求授权
B. 返回授权资格
C. 获取访问资格token(用上一步的token获取)
D. 返回访问token
E. 使用access token访问所需资源
F. 获得相应资源
授权所需的信息
- 应用名称
- 应用站点
- 重定向URI或回调URL(redirect_uri)
- 客户端表示 client_id
- 客户端秘钥client_secret (获取token加密使用的)
- state(非必选),会保存在client端,防止CSRF攻击
四种授权方式
1. 授权码模式
最完整的授权方式,在web app中应用最广
- 所需参数
| 字段 | 描述 |
|---|---|
| response_type | 必选,固定位code,表示这个授权码请求 |
| client_id | 必选,在授权服务器注册应用后得到的唯一标识 |
| redirect_uri | 可选,通过客户端注册的重定向URI(要去与注册时一致) |
| scope | 可选,表示权限范围,如果存在,原样返回给客户端 |
| refresh_token | 可选,表示更新令牌,用来获取下次访问的令牌 |
2. 简化模式
URL e.g: https//:ruby-china/callback?token=*****&state=*****
- token会暴露,如上
3. 密码模式
- 登录,输入用户名和密码
- 请求认证服务器
- 获取access token
- 请求响应资源
- 这种方式很蠢,尽量不要用,除非你非常相信这个第三方的客户端。因为有可能会把账号密码信息存到第三方
4. 客户端模式 Client Credentials Grant
-
直接根据客户端的秘钥和ID获取token,不需要客户参与 e.g: 可以通过通过Basic Auth的方式向服务端获取认证,直接获取token
-
比较适合消费API的后端服务,不支持refresh token
小结
- 授权码: 正宗的OAuth认证,推荐(安全性最好)
- 密码模式:为遗留项目做修补 (有安全隐患,客户端可能存了用户的密码和用户名)
- 简化模式:为web浏览器设计:(token被明文发送)
- 客户端模式:为后台API服务消费者设计 (推荐设置token的过期,不支持refresh token)
token相关的补充
- 传统的认证方式一般采用cookie/session来实现,但是我们为什么用token,那什么又是refresh token,以及它的原理是什么?带着疑问,我们往下看。
1. 为什么我们使用token而不是用cookie或者session?
首先不管是token,cookie还是session,它们其实都是一个字符串,但是token是自带加密算法和用户信息的(如userId); 然而cookie本身是不包含任何用户信息的,它指向的是服务器上的用户session,session用来保存用户信息。这点差别决定token可以很容易跨服务器使用,只要不同服务器实现相同的解密算法就可以,而cookie/session是存在于某以太服务器上,不会跟着请求走。这就造成了cookie/session应用天生的短板
2. token需要过期时间么?
- token是资源获取的凭证,所以我们当然要设置过期时间,不然如果token被劫持而且永远不过期,那坏人们就可以一直用这个token来访问受害者的资源。当然token的过期时间并不是强制的。
- 参考主流网站的token过期时间,一般不超过1h
3. token过期的怎么办啊?
- token过期了那就再获取新的token(access token 具有资源访问权限的token)呗,有两种方式。
- 重复首次获取token的过程(如登录,扫描二维码授权),但是用户体验不好。每过1h后再让你重新登录,或者扫码...反正我是忍受不了。
- 提供另一个用户获取新token的refresh token。这个token是专门获取access token的不涉及资源的权限。当然这个refreash token也是有过期时间的但是过期时间可以设置的相对长一些,而且当我们再次获取新的access token的时候这个refresh token也可以被更新。一般可以设置成几天,根据应用场景定。另外如果客户端是个服务器,那么这个refresh token甚至可以设成永久有效的,直到下次登录时再刷新它。
4. 另外说点啥:
- 任何安全策略都不是理论上或者安全上完全的安全的。但是我们只要把”破解“这个过程做的相当麻烦,那它就是一个相对安全的策略,因为破解成本会提升。