前言
做后台开发,难免需要与第三方系统打交道,可能是调用第三方的服务,又或是需要用户在第三方系统
的相关信息等。前者多以webservice方式提供,后者则采用OAuth协议提供,也是下面要讲的。
OAuth(Open Authorzation)介绍
官方网站对oAuth有如下介绍:
An open protocol to allow secure API authorization in a simple and standard method from
web, mobile and desktop applications.大概的意思是说OAUTH是一种开放的协议,为桌面、手机
或web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。该协议的最大好处就是它
与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),
即第三方无需使用用户的用户名与密码就可以申请获得该用户授权的资源。
OAuth协议相关术语介绍
Third-party application:第三方应用
HTTP service:服务提供商
User Agent:用户代理(下文中又称浏览器)
Authorization server:认证服务器(服务提供商专门用来处理认证的服务器)
Resource server:资源服务器
OAuth协议的目标:1.第三方应用需经用户授权后,方可使用用户在服务提供商的资源服务器上的资源
2.资源由用户决定
3.第三方应用应不触及到用户的帐号信息(安全的)
OAuth流程介绍
1.用户访问第三方应用后,要求用户在授权。
2.用户同意向第三方授权,并指明授权的资源。
3.第三方使用上一步获得的授权,向认证服务器申请令牌。
4.第三方使用令牌,向资源服务器申请获取用户资源。
5.资源服务器确认令牌后,开放用户资源给第三方。
从上面流程中,我们可以看出满足了OAuth协议的目标。上述流程中最关键的步骤发生在第2步,即用户
授权,OAuth协议规定了四种授权模式:
authorization code model:授权码模式
Implicit model:简化模式
resource owner password credentials model:密码模式
client credentials model:客户端模式
授权模式
下面我们就介绍这四种授权模式:
1).授权码模式流程图:
流程介绍:
1.用户访问第三方,后者将前者重定向到认证服务器(申请认证)。
2.用户选择是否给予客户端授权以及资源权限。
3.若用户给予授权,认证服务器将用户导向第三方事先指定的"URI",并附上一个授权码。
4.第三方拿到授权码,附上早先的"URI",向认证服务器申请令牌。
5.认证服务器核对了授权码和URI,通过后,返回给第三方访问令牌和更新令牌。
下面介绍流程中,所涉及到的参数:
第一步申请认证的URI包含参数:
response_type:授权类型,此处的值固定为"code" ,必选项
client_id:表示第三方的ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示第三方的当前状态,任意值,认证服务器会原样地返回,可选项
第三步认证服务器回应第三方的URI包含参数:
code:授权码。有效期应很短,通常设为10分钟,且第三方只能使用该码一次,会被认
证服务器拒绝(该码与第三方ID和重定向URI,存在对应关系)。必选项
state:如果第三方的请求中包含该参数,认证服务器的回应也必须包含这个参数。
第四步申请令牌(以http方式请求)包含参数:
grant_type:使用的授权模式,该值固定为"authorization_code",必选项
code:获得的授权码,必选项。
redirect_uri:重定向URI,且必须与A步骤中的该参数值保持一致,必选项
client_id:第三方ID,必选项。
第五步认证服务器返回的参数:
access_token:访问令牌,必选项。
token_type:令牌类型(bearer/mac类型),该值大小写不敏感,必选项
expires_in:过期时间(秒)。如果省略该参数,必须其他方式设置过期时间。
refresh_token:更新令牌,令牌过期后用来获取下一次的访问令牌,可选项。
scope:权限范围,如果与第三方申请的范围一致,此项可省略。
下面通过案例来理解授权码模式的OAuth协议
访问某网站首页,页面有qq登录和微博登录,我们选择qq登录
浏览器会重定向到qq的认证服务页面,我们将location值拿出来看看https://graph.qq
.com/oauth/show?which=Login&display=pc&response_type=code&client_id=101249010
&state=30c504bb633f29857aadffed4c5d669a&scope=get_user_info%2Cget_info%2Ca
dd_t%2Cdel_t%2Cadd_pic_t%2Cget_repost_list%2Cget_other_info%2Cget_fanslist
%2Cget_idollist%2Cadd_idol%2Cdel_idol&redirect_uri=http%3A%2F%2Fwww.newbiefl
y.com%2F%3Fconnect%3Dqq
我们可以看到包含response_type,client_id,state,scopt,redirec_url 5个参数,对应授
权码模式的第一步--申请认证,这时用户指定资源权限后我们点击授权按钮。
这时就登录进来了,可以看到是qq认证服务器重定向了浏览器,提取location的值如下:
http://www.newbiefly.com/?connect=qq&code=C3EF94F8DDCA92FB23FE726B0BF4CC
8D&state=30c504bb633f29857aadffed4c5d669a,可以看出认证服务器回应该申请网站code
以及state,对应对应授权码模式的第三步。
第四,五步是后台通过代码模拟http请求调用的,用户是不可见的。
以上是基于授权码模式的OAuth协议流程。
2).简化模式流程图
流程介绍:
1.用户访问第三方,后者将前者重定向到认证服务器(申请认证)。
2.用户选择是否给予客户端授权以及资源权限。
3.若用户给予授权,认证服务器将用户导向第三方事先指定的"URI",并以URI的hash部分包
含访问令牌等信息。
4.浏览器向资源服务器发出请求。
5.资源服务器返回一个网友,其中js脚步可以获取Hash值的令牌。
6.提取令牌后,浏览器访问第三方(包含令牌信息)。
下面介绍流程中,所涉及到的参数:
第一步申请认证的URI包含参数:
response_type:授权类型,此处的值固定为"code" ,必选项
client_id:表示第三方的ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示第三方的当前状态,任意值,认证服务器会原样地返回,可选项
注意:response_type的值为code。
第三步认证服务器回应第三方的URI包含参数:
access_token:访问令牌,必选项。
token_type:令牌类型,该值大小写不敏感,必选项。
expires_in:过期时间(秒)。如果省略该参数,必须其他方式设置过期时间。
scope:权限范围,如果与第三方申请的范围一致,此项可省略。
state:如果第三方的请求中包含该参数,认证服务器的回应也必须包含这个参数。
注意:此时浏览器得到http头的location参数值为:URI#access_token=..&token_type=
这种形式;URI的值为资源服务器上的。
第五步资源服务器返回的页面会执行js代码用于获取Hash值的access_token,
token_type等参数,再将数据包含在访问第三方URI的请求中。
以上是基于简化模式的OAuth2.0协议的流程。
3).密码模式流程图
用户向第三方提供自己的用户名和密码,客户端使用这些信息,向"服务商提供商"索要授权(客户
端不得储存密码),该模式基本不使用(也违背OAuth协议的初衷,只有在其他授权模式无法执行
的情况下,才考虑)。
上图中B为第三方发出http请求包含的参数:
grant_type:授权类型,此处的值固定为"password",必选项。
username:用户名,必选项。
password:用户的密码,必选项。
scope:表示权限范围,可选项。
上图C为响应第三方的http请求包含的参数:查看授权码模式流程图的第五步。
以上是基于密码模式的OAuth2.0模式的流程。
客户端模式流程图
该模式是以第三方的名义向认证服务器进行认证授权。
上图中A为第三方发出http请求包含的参数:
granttype:授权类型,此处的值固定为"clientcredentials",必选项。
scope:权限范围,可选项。
上图B为响应第三方的http请求包含的参数:查看授权码模式流程图的第五步。
以上是基于客户端模式的OAuth2.0模式的流程。
参考:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html