OAUTH 2.0深入了解:以微信开放平台统一登录为例
Posted 程序猿小卡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OAUTH 2.0深入了解:以微信开放平台统一登录为例相关的知识,希望对你有一定的参考价值。
一、什么是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来代替。
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"
}
四、以微信授权为例
以微信开放平台统一登录为例,更多细节可参考 官方文档。
下图为微信统一登录的时序图:
步骤分解如下:
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深入了解:以微信开放平台统一登录为例的主要内容,如果未能解决你的问题,请参考以下文章