OAUTH 2.0深入了解:以微信开放平台统一登录为例

一、什么是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直接给到用户侧。

相对于用户侧网络环境的复杂性,应用自身服务端的网络环境相对更可控些。但这并不意味着就绝对安全。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180226G05ZAS00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券