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

Posted 程序猿小卡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OAUTH 2.0深入了解:以微信开放平台统一登录为例相关的知识,希望对你有一定的参考价值。

一、什么是OAuth 2.0

简单的说,OAuth 2.0是个授权框架。它定义了第三方应用如何通过用户授权,来访问用户的受限资源。

举个例子,个人网站要支持微信账号登陆,微信开放平台的授权登陆就用到了OAuth 2.0。

OAuth 2.0 涉及的关键参与方有:

  1. Resource Owner:资源所有者。这里指微信用户。

  2. Third-party application:第三方应用。这里指个人网站。。

  3. Authorization server:授权服务器。这里指微信开放平台的授权服务。

  4. Resource server:资源服务器,用来存储、获取用户资源。这里指的是微信开放平台的服务器。

二、OAuth 2.0 基本流程

OAuth 2.0 主要包含两个关键步骤:

  1. 第三方应用取得用户授权。

  2. 第三方应用访问用户资源。

其中,“取得用户授权“是流程重点,最终取得的授权凭证叫做access token。如下图所示:

如上图所示,access token的获取分为两步:

  1. 获取授权码code,这是临时授权凭证:步骤A、B、C、D。

  2. 通过code交换access token,这是正式授权凭证:步骤E、F。

获取 access token 的细节是本文重点,下一节会进行介绍。

三、如何获取access token

有多种方式可以获取access token,这里主要介绍最常见授权码模式(Authorization Code Grant)。

授权码模式 流程如下:

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

跳过具体细节,看下各步骤具体做了什么:

  1. 步骤A、B:第三方应用取得用户授权。

  2. 步骤C:第三方应用取得授权码(authorization code)。

  3. 步骤D:第三方应用请求授权凭证(access token)。

  4. 步骤E:第三方应用获得授权凭证(access token)。

User-Agent:前端开发的同学应该不陌生,大部分时候指的就是浏览器。

接下来,稍微详细点讲解各个步骤:

1、请求用户授权

  • response_type:必选,请求类型。这里固定为"code"。

  • client_id:必选,标识第三方应用的id。很多地方也用apppid来代替。

  • scope:可选,第三方请求的资源范围。比如是想获取基本信息、敏感信息等。

  • state:推荐,用于状态保持,可以是任意字符串。授权服务会原封不动地返回。

对于redirect_uri是可选的,大家可能会有疑惑。在实际中,redirect_uri 一般在应用后台就完成了填写和验证,因此可以是选填的。

2、用户授权返回

  • 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。

例子如下:

     HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Cache-Control: no-store
    Pragma: no-cache
    {
      "access_token":"2YotnFZFEjr1zCsicMWpAA",
      "token_type":"example",
      "expires_in":3600,
      "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
      "example_parameter":"example_value"
    }

四、以微信授权为例

以微信开放平台统一登录为例,更多细节可参考 官方文档。

下图为微信统一登录的时序图:

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

步骤分解如下:

1、请求用户授权:步骤2、3、4

带上appid、redirect_uri、response_type、scope、state。其中:

  • appid:应用id,就是前面提到的client_id。

  • response_type:响应类型,固定为"code"。

  • scope:授权许可范围,固定为"snsapi_login"。

  • state:可选,授权服务回传。

2、用户授权返回:步骤5

用户同意授权,重定向到 redirect_uri, 并返回临时票据code。如下所示:

redirect_uri?code=CODE&state=STATE

3、请求access token

应用拿到临时票据后,用临时票据去换取真实票据 access token。所需参数如下:

  • appid:必选,应用id。

  • secret:必选,应用秘钥,在微信后台生成。

  • code:必选,前面获取的授权码。

  • grant_type:必选,值固定为"authorization_code"

4、返回access token

微信后台经过验证,确认请求合法后,将access token返回给第三方应用。

返回例子如下:

{ 
   "access_token":"ACCESS_TOKEN",
   "expires_in":7200,
   "refresh_token":"REFRESH_TOKEN",
   "openid":"OPENID",
   "scope":"SCOPE",
   "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

除前面提到的access_token、refresh_token、expires_in,这里还返回了 openid、unionid,这两者是用户信息,微信体系特有的,不展开。

五、为什么不直接返回access_token

在授权码模式下,授权服务先返回授权码code给第三方应用,第三方应用再利用授权码来换取access token。

为什么不直接返回access token呢?

主要是出于安全方面的考虑。

假设第三方应用、授权服务不直接通信,中间隔了一层代理。同时,第三方应用采用HTTP协议,那么,恶意代理就可以窃取access token。

这就是所谓的中间人攻击。

因此,采用了通过code来交换access token的方式,来增加安全性。并且,不能将access token直接给到用户侧。

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

如果微信开放平台的接口是基于HTTP的,那么不单access token,连secret也有被截获的的风险。

六、相关链接

OAuth 2.0规范
https://tools.ietf.org/html/rfc6749


为什么需要authorization_code
https://stackoverflow.com/questions/13387698/why-is-there-an-authorization-code-flow-in-oauth2-when-implicit-flow-works-s


微信网页授权
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842



以上是关于OAUTH 2.0深入了解:以微信开放平台统一登录为例的主要内容,如果未能解决你的问题,请参考以下文章

开放平台OAuth 2.0授权开发实践

微信订阅号里实现oauth授权登录,并获取用户信息 (完整篇)

微信开放平台开发 移动应用微信登录

微信开放平台开发——网页微信扫码登录(OAuth2.0)

微信开放平台开发——网页微信扫码登录(OAuth2.0)

php微信开放平台--第三方网页微信扫码登录(OAuth2.0)