OAuth认证流程、Access Token以及Refresh Token简介

OAuth认证流程

背景

很多的网站、APP都弱化了甚至没有搭建属于自己的账号体系,而是使用其它社会化的第三方登陆的方式,比如在登陆某个网站的时候选择通过github或者微信、微博等方式登陆,这样不仅免去了用户注册账号的麻烦,还可以获取用户的好友关系来增强自身的社交功能。

例如要通过github这样的第三方网站去登陆某个没有自己账号体系的平台,最传统的方式是直接在该平台的登陆页面输入github的账号密码,该平台通过用户的账号和密码去github上面获取用户的数据,但是这样做有很多缺陷:

  1. 该平台需要明文保存用户的github账号和密码,不安全;
  2. 该平台拥有获取用户在github的所有权限;
  3. 用户只有修改密码,才能收回赋予该平台的权限,会导致其它获得用户授权的第三方应用全部失效;
  4. 只要有一个第三方应用程序被破解,就会导致用户密码泄露,以及所有使用github登陆过的网站的数据泄漏;

为了解决以上问题,就有了OAuth。

原理

OAuth在“客户端”和“服务端”之间设置了一个授权层(authorization layer)。“客户端”不能直接登陆“服务端”,只能登陆授权层,以此将用户与客户端区分开来。“客户端”登陆授权层所用的oken与用户的密码不同,用户可以在登陆的时候,指定授权层token的权限范围和有效期。

“客户端”登陆授权层之后,“服务端”根据token的权限范围和有效期,向“客户端”开放用户存储的资料。

例如现在有一个平台为平台A,平台A的登陆方式只有通过谷歌账号第三方登录机制登录。流程图大致如下:
流程图

  1. 用户点击Sign in with Google
    跳转到授权页面,授权页面的URL中主要包含的参数有:
  • client_id: 在Google中申请应用ID;
  • redirect_uri: 授权成功之后要跳转到的地址;
  1. 页面自动跳转到初始参数中redirect_uri定义的URL,并自动在URL末尾添加一个code参数
  2. 平台A通过上一步获取的code参数换取Token,平台A请求如下接口获取Token
    POST https://oauth2.googleapis.com/token,需要包含以下参数:
  • client_id: 在Google申请的应用ID;
  • client_secret: 在Google申请时提供的APP Secret;
  • grant_type: 需要填写authorization_code;
  • code: 上一步获得的code;
  • redirect_uri: 回调地址,需要与注册应用里的回调地址以及第一步的redirect_uri参数一致;
  1. 通过第三步的请求,接口返回Token和相关数据
{
	"access_token": "ACCESS_TOKEN",		// Token的值
	"expires_in": 1000,		// 过期时间
	"uid": "1234567", 		// 当前授权用户的UID
}
  1. 使用在第四步中获取到的access_token,就可以去获取用户的资源了
  2. Google返回用户信息,平台A进行处理,整个流程结束;

通过以上方式,在平台A和Google之间建立了一个独立的权限层,这个权限由用户赋予,可以被用户随时取消,不同于第三方应用之间的相互独立,互不干扰,这样就解决了明文存放账号密码的问题。

Access Token

Access Token是用于访问被保护的资源的一种凭据,它是一个不透明的字符串。一般Access Token的有效时间都比较短,如果想要用户不用频繁登录平台A,就需要用到Refresh Token了。至于为什么需要用到Refresh Token而不是再次去获得Access Token,主要是因为获取Access Token的时候需要使用到一个code,而生成这个code需要用户再次进行操作,而有了Refresh Token,用户就可以不用再次进行操作了。

Refresh Token

在OAuth机制中,Refresh Token并不是必须设置的,但是不设置Refresh Token,则会增加用户登录的次数。Refresh token的作用是刷新Access token。为Refresh Token是保存在客户端的服务器上的,当前的Access Token失效或者过期时,Refresh Token就会去获取一个新的Token,Refresh Token也是一个对客户端不透明的字符串。

一个比较有效的token返回结果如下:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
 
{
  "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
  "token_type":"bearer",
  "expires_in":3600,
  "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
  "scope":"create"
}

大致流程如下:
在这里插入图片描述

  1. 客户端通过认证服务器请求认证;
  2. 认证服务器检验客户端认证是否有效,如果有效,返回一个Access Token和一个Refresh Token;
  3. 客户端通过Access Token去请求服务器的资源;
  4. 如果Access Token有效,服务器返回给客户端资源,如果Access Token失效,服务器返回给客户端Token失效的信息,然后客户端会通过Refresh Token再次请求获取新的Access Token;

Refresh Token本身也是有过期时间的,一般会比Access Token的过期时间长很多,如果想要将Refresh Token设置为永久有效,则可以通过配置参数实现。

参考链接:

http://www.rfcreader.com/#rfc6749
https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值