一、什么是OAuth 2.0
简单的说,OAuth 2.0是个授权框架。它定义了第三方应用如何通过用户授权,来访问用户的受限资源。
OAuth 2.0 涉及的关键参与方有:
Resource Owner:资源所有者。这里指微信用户。
Third-party application:第三方应用。这里指个人网站。。
Authorization server:授权服务器。这里指微信开放平台的授权服务。
Resource server:资源服务器,用来存储、获取用户资源。这里指的是微信开放平台的服务器。
二、OAuth 2.0 基本流程
OAuth 2.0 主要包含两个关键步骤:
第三方应用取得用户授权。
第三方应用访问用户资源。
其中,“取得用户授权“是流程重点,最终取得的授权凭证叫做access token。如下图所示:
如上图所示,access token的获取分为两步:
获取授权码code,这是临时授权凭证:步骤A、B、C、D。
通过code交换access token,这是正式授权凭证:步骤E、F。
获取 access token 的细节是本文重点,下一节会进行介绍。
三、如何获取access token
有多种方式可以获取access token,这里主要介绍最常见授权码模式(Authorization Code Grant)。
授权码模式 流程如下:
授权码模式
跳过具体细节,看下各步骤具体做了什么:
步骤A、B:第三方应用取得用户授权。
步骤C:第三方应用取得授权码(authorization code)。
步骤D:第三方应用请求授权凭证(access token)。
步骤E:第三方应用获得授权凭证(access token)。
User-Agent:前端开发的同学应该不陌生,大部分时候指的就是浏览器。
接下来,稍微详细点讲解各个步骤:
1、请求用户授权
第三方应用,将资源所有者导向一个特定的地址,并在地址里带上如下信息:
response_type:必选,请求类型。这里固定为"code"。
client_id:必选,标识第三方应用的id。很多地方也用apppid来代替。
redirect_uri:可选,授权完成后重定向的地址。当取得用户授权后,授权服务会重定向到这个地址,并在地址里带上授权码。
scope:可选,第三方请求的资源范围。比如是想获取基本信息、敏感信息等。
state:推荐,用于状态保持,可以是任意字符串。授权服务会原封不动地返回。
对于redirect_uri是可选的,大家可能会有疑惑。在实际中,redirect_uri 一般在应用后台就完成了填写和验证,因此可以是选填的。
2、用户授权返回
资源所有者,同意授权第三方应用访问受限资源后,请求返回,跳转到 redirect_uri 指定的地址。
地址中带了如下信息:
code:必选,授权码。后续步骤中,用来交换access token。
state:必选(如果授权请求中,带上了state),这里原封不动地回传。
3、请求access token
第三方应用,向授权服务请求获取access token。请求参数包括:
grant_type:必选,许可类型,这里固定为“authorization_code”。
code:必选,授权码。在用户授权步骤中,授权服务返回的。
redirect_uri:必选,如果在授权请求步骤中,带上了redirect_uri,那么这里也必须带上,且值相同。
client_id:必选,第三方应用id。
4、返回access token
请求合法且授权验证通过,那么授权服务将access token返回给第三方应用。
关键返回字段:
access token:必选,访问令牌,第三方应用访问用户资源的凭证。
expires_in:推荐,access token的有效时长。
refresh token:可选,更新access token的凭证。当access token过期,可以refresh token为凭证,获取新的access token。
例子如下:
四、以微信授权为例
以微信开放平台统一登录为例,更多细节可参考 官方文档。
下图为微信统一登录的时序图:
步骤分解如下:
1、请求用户授权:步骤2、3、4
带上appid、redirect_uri、response_type、scope、state。其中:
appid:应用id,就是前面提到的client_id。
redirect_uri:授权回调的地址,在微信管理后台填写。
response_type:响应类型,固定为"code"。
scope:授权许可范围,固定为"snsapi_login"。
state:可选,授权服务回传。
2、用户授权返回:步骤5
用户同意授权,重定向到 redirect_uri, 并返回临时票据code。如下所示:
3、请求access token
应用拿到临时票据后,用临时票据去换取真实票据 access token。所需参数如下:
appid:必选,应用id。
secret:必选,应用秘钥,在微信后台生成。
code:必选,前面获取的授权码。
grant_type:必选,值固定为"authorization_code"
4、返回access token
返回例子如下:
除前面提到的access_token、refresh_token、expires_in,这里还返回了 openid、unionid,这两者是用户信息,微信体系特有的,不展开。
五、为什么不直接返回access_token
在授权码模式下,授权服务先返回授权码code给第三方应用,第三方应用再利用授权码来换取access token。
为什么不直接返回access token呢?
主要是出于安全方面的考虑。
假设第三方应用、授权服务不直接通信,中间隔了一层代理。同时,第三方应用采用HTTP协议,那么,恶意代理就可以窃取access token。
这就是所谓的中间人攻击。
因此,采用了通过code来交换access token的方式,来增加安全性。并且,不能将access token直接给到用户侧。
相对于用户侧网络环境的复杂性,应用自身服务端的网络环境相对更可控些。但这并不意味着就绝对安全。
领取专属 10元无门槛券
私享最新 技术干货