为什么不单独使用access_token还要搞出一个fresh_token?结论是:为了更加安全,具体情况我们娓娓道来。
OAuth2.0协议是通用的授权协议,用于第三方应用向用户获取授权并访问用户资源的场景,最美妙的是,用户并不需要将自己的凭据(比如账号密码)直接交给第三方应用。
OAUTH2.0的组成和工作流程
OAuth 定义了四个角色,他们分别是:
①资源所有者(Resource Owner)
能够授权访问它的受保护资源的实体,如果他是一个人的时候,我们称他为 终端用户(end-user)
②资源服务器(Resource Server)
托管受保护资源的服务器,能够通过判定access_token是否有效来决定是否允许访问特定的资源。
③客户端(Client)第三方应用
客户端因为拿到了用户(资源所有者)的授权,所以可以代表用户访问他的资源。客户端并不指特定的实现(应用可以是服务器、桌面应用、或者设备)
④授权服务器(Authorization server)
用户发起请求,授权服务器验证用户的凭据后并根据用户的授权签发access_token(访问令牌)给客户端。
上面的图描述了四个角色之间的交互流程
(A)客户端向资源所有者请求授权,授权请求可以直接向资源所有者发起,也可以通过授权服务器作为中介间接进行(这种方式更好)。
(B)客户端拿到用户的授权许可,得到一个凭据,这个凭据就表示资源所有者同意授权了,可以使用本文档中定义的四种授权方法进行(当然也可以使用自定义扩展的方法)。授权方法主要由客户端决定,当然授权服务器支不支持也会受到影响。
(C)客户端拿着上一步获取到的凭据标示向授权服务器申请access_token(访问令牌)
(D)授权服务器检查凭据是否有效,如果有效则签发access_token给客户端。
(E)客户端通过携带access_token向资源服务器发起访问受保护资源的请求。
(F)资源服务器检查access_token的有效性,如果有效则提供对应资源。
客户端获取 凭据 最好的方法是通过授权服务器作为中介进行(步骤A和B中)
一句话表达式:第三方应用向用户要授权,将用户跳转到用户资源所在的授权服务器上,用户在授权服务器同意授权后授权服务器交给第三方应用一个ticket,然后第三方应用使用这个ticket获取真正能够访问用户资源的access_token.
这个流程中授权服务器一般会同时给第三方应用一个短期有效的access_token和一个长期有效的refresh_token,当access_token失效时可以使用refresh token获取新的access_token。这个流程是不是看上去脱裤子放屁,多此一举,其实并不是,通过下面这张图就能明白设计的原因:
refresh_token 只和授权服务器进行交互,而access_token则只和资源服务器通信。
看懂了吧,这就是最初设计的本质,按照设计,第三方应用的服务器保存refresh_token并通过refresh_token和授权服务器通信拿到access_token再交给自己的应用,这样安全性大大提升,服务器之间通信频率极低,且更难窃听。
下面翻译下RFC6749中对access_token和Refresh_token的描述
access_token
access_token是客户端透明的,这串字符串中包含了允许的授权范围以及有效时间等,资源服务器和授权服务器都知道这个access_token的情况
token自身也许包含一些额外的信息,比如token表示用户等(比如JWT形式)
token提供了一个抽象层,通过单一的token字符串的形式而不是比如用户名密码形式,资源服务器明白这个token的含义。
Refresh_token
刷新token的作用是为了获取access_token,refresh_token会比access_token时间更长,设计目的仅仅是 客户端和授权服务器之间通信用的,而access_token则是客户端和资源服务器之间通信用的。