【转载】OAuth 2.0详细说明

  原文地址:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

  原作者:阮一峰

  注:原作者授权,可自由转载。

 

  OAuth2.0发布编号为RFC6749,OAuth2.0与OAuth1.0不兼容,1.0就不提了。  

 

  简述一个场景:

    使用QQ帐号登录新浪微博。简单粗暴的方法是,QQ的帐号和密码直接告诉新浪微博,新浪微博用你的QQ帐号和密码直接登录QQ,获取QQ的相关信息(昵称、性别、爱好等),作为新浪微博的基础资料。目的是达到了,同时带来许多的问题,主要是新浪微博获得了与你完全一致的权限,非常不安全。

 

  OAuth2.0解决方案思路是在QQ和新浪微博之间增加授权层(authorization layer),新浪微博只有登录授权层的权限,当然所使用的也不是帐号密码,而是令牌(token),令牌是能够限定新浪微博访问的范围,如:只能获取昵称。首先介绍下其引入的角色,见下图。

  那么增加了授权层的授权流程如下:

    

  其中的client等价于新浪微博,数据流程是依次是A、B、C、D、E、F;核心点在于B是如何实现,因为B步骤后面就是Access_Token起效果了。

  B步骤,客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0定义了四种授权方式。

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)  

 

  授权码模式(authorization code)是功能最完整、流程最严密的授权模式。所以此处我只是摘抄了授权码模式的。它的特点就是通过client的后台服务器,与http server的认证服务器进行互动。

    (A)用户访问client,后者将前者导向Auhorization Server。

    (B)用户选择是否给予client授权。

    (C)假设用户给予授权,Authorization将用户导向client事先指定的"重定向URI"(redirection URI),同时附上一个授权码。

    (D)Client收到授权码,附上早先的"重定向URI",向Authorization Server申请令牌。这一步是在Client的后台的服务器上完成的,对用户不可见。

    (E)Authorization核对了授权码和重定向URI,确认无误后,向Client发送访问令牌(access token)和更新令牌(refresh token)。

A步骤中,客户端申请认证的URI,包含以下参数:

  • response_type:表示授权类型,必选项,此处的值固定为"code"
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

  一个例子如下:

  GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
  Host: server.example.com

C步骤中,服务器回应客户端的URI,包含以下参数:

  • code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
  • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

下面是一个例子。

  HTTP/1.1 302 Found
  Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

D步骤中,客户端向认证服务器申请令牌的HTTP请求,包含以下参数:

  • grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。
  • code:表示上一步获得的授权码,必选项。
  • redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
  • client_id:表示客户端ID,必选项。

下面是一个例子。

  POST /token HTTP/1.1
  Host: server.example.com
  Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
  Content-Type: application/x-www-form-urlencoded

  grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

 

E步骤中,认证服务器发送的HTTP回复,包含以下参数:

  • access_token:表示访问令牌,必选项。
  • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
  • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  • refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
  • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。

下面是一个例子。

     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"
     }

 从上面代码可以看到,相关参数使用JSON格式发送(Content-Type: application/json)。此外,HTTP头信息中明确指定不得缓存。

 

    

 

posted @ 2016-08-27 14:26  wildfox  阅读(122)  评论(0编辑  收藏  举报