在上一篇文章中(OAUTH2验证框架之入门教程)中,我们已经讲到了Oauth2验证框架的事情事理。
知道Oauth2验证框架事情的六个步骤:

(A)用户打开客户端往后,客户端哀求用户给予授权

(B)用户赞许给予客户端授权。

oauth2serverphp办事器Oauth2验证框架之项目实现 Ruby

(C)客户端利用上一步得到的授权,向认证做事器申请令牌

(D)认证做事器对客户端进行认证往后,确认无误,赞许发放令牌。

(E)客户端利用令牌,向资源做事器申请获取资源。

(F)资源做事器确认令牌无误,赞许向客户端开放资源。

那么在详细的项目中,真正是怎么实现的呢?针对这个问题,本文下面将重点先容。

Oauth2.0是一个很通用的验证框架,很多编程措辞都对其进行了实现,包括Java、PHP、Python、NodeJS、Ruby、NET、Erlang、Go、C等。
大家可以在如下页面,查看自己所利用措辞的实现方案。

https://oauth.net/code/

本文以PHP的实现方案为例,来讲述Oauth2在项目中的事情流程。
Java、Python、NodeJS、Ruby、NET、Erlang、Go、C等措辞在项目中的事情流程,大家可以对照PHP的描述,自行交融贯通。

bshaffer/oauth2-server-php是一个库,可以实现符合标准的OAuth 2.0做事器。
利用它您的用户可以对运用程序客户端进行身份验证和授权,并保护您的API。

在详细讲述bshaffer/oauth2-server-phpr的详细实现之前,我们先理解一下个中涉及到的几个主要观点:

授权模式(Grant Types):付与类型许可您展示客户端吸收令牌的多种办法。

掌握器(Controllers):OAuth做事器有3个端点,每个端点都可以由掌握器进行配置。
每个端点都在OAuth进程中实行不同的功能。
授权端点(Authorize Endpoint):用户在这里由客户端重定向来授官僚求。
令牌端点(Token Endpoint) :客户端向该端点发出要求以得到访问令牌。
资源端点(Resource Endpoint(s)) :客户端要求资源,为认证令牌供应访问令牌。
该库支持许多不同的授权类型,包括官方OAuth规范定义的所有授权类型。

存储工具(Storage Objects):该库利用存储接口来许可与多个数据层进行交互。
PDO、Redis、Mongo、Cassandra、Doctrine Storage等存储类随库供应,但接口大概可您进行自定义。

其他观点:Response Object、Scope、User IDs、JWT Access Tokens

授权模式(Grant Types)

bshaffer/oauth2-server-php库已经实现了OAuth 2.0授权框架RFC中定义的所有授权模式:

授权码模式(authorization code)

简化模式(implicit)

密码模式(resource owner password credentials)

客户端模式(client credentials)

掌握器(Controllers)

大多数OAuth2 API将具有授官僚求、令牌要乞降资源要求的端点。
OAuth2 \ Server工具具有处理每个要求的方法。
下面的每个掌握器通过相同的名称对应于端点:

1、授权掌握器

对付授权端点,哀求用户利用授权码(授权码模式)或访问令牌(简化模式)对客户端进行认证和重定向。
它有两个方法:

handleAuthorizeRequest

validateAuthorizeRequest

handleAuthorizeRequest()的浸染是吸收授官僚求,返回授权相应。

validateAuthorizeRequest()的浸染是吸收授官僚求,如果传入要求不是有效的授官僚求,则返回false。
如果要求有效,则返回检索到的客户端详细信息和输入数组。
在向用户显示登录或授权表单之前,运用程序该当调用它。

2、资源掌握器

对付任何必要oauth2身份验证的资源要求(即API调用)。
掌握器将验证传入的要求,然后许可运用程序返回受保护的资源。
它有两个方法:

verifyResourceRequest

getAccessTokenData

verifyResourceRequest()的浸染是吸收访问资源的要求,根据要求判断访问令牌(access token)是否存在,不管要求是否合法,将返回一个布尔值(true or false)。

getAccessTokenData()的浸染是讲吸收的要求作为参数,如果该要求有被授权返回访问令牌(access token),否则返回null。

3、令牌掌握器

对付利用配置的授权类型的令牌端点,将访问令牌(access token)返回给客户端。
它有两个方法:

grantAccessToken

handleTokenRequest

grantAccessToken()的浸染是吸劳绩取访问令牌(access token)的要求,如果要求有效,将返回访问令牌(access token)。

handleTokenRequest()的浸染是吸劳绩取访问令牌(access token)的要求,返回适当相应的相应工具

存储工具

该库支持多个不同存储引擎的适配器。
个中包括PDO(用于MySQL,SQLite,PostgreSQL等),MongoDB,Redis和Cassandra。
这是通过多个PHP接口完成的,这个接口决定了如何存储不同的工具。
接口许可对多个平台进行扩展和定制,使得编写自己的存储类随意马虎。
存储接口还可以轻松地将工具存储在多个数据存储系统中。

下载安装

1、哀求

这个库须要PHP 5.3.9+。
但是,PHP 5.2.x-5.3.8也有一个稳定的发布和开拓分支。

2、下载

这个库托管在GitHub上,如果不能利用composer工具,大家也可以在如下页面下载利用:

https://github.com/bshaffer/oauth2-server-php

3、安装

这个库遵照zend PSR-0标准。
有许多自动加载器可以自动加载这个库,但是如果你不该用它,你可以手动注册OAuth2 \ Autoloader,如下:

如果你可以利用composer工具,可以直策应用如下命令,这个库将自动加载到你的项目中:

composer.phar require bshaffer/oauth2-server-php \"大众^1.10\"大众

开始利用

前面已经讲到,OAuth2 Server库已经实现了OAuth 2.0授权框架RFC中定义的所有授权模式,包括:授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password credentials)、客户端模式(client credentials)。
下面我们来逐一解释。

把稳:我们这里假设我们的授权做事器的域名为:

https://api.mysite.com

资源做事器的域名为:

https://myredirecturi.com

1、授权码模式(authorization code)

授权码模式是功能最完全、流程最严密的授权模式。
它的特点便是通过客户真个后台做事器,与\"大众做事供应商\"大众的认证做事器进行互动。
如图:

详细实现如下:

①、创建一个OAuth2 \ GrantType \ AuthorizationCode的实例并将其添加到您的做事器,如下:

②、当用户访问资源做事器时,我们将其导引到授权做事器,如下:

https://api.mysite.com/authorize?response_type=code&client_id=TestClient&redirect_uri=https://myredirecturi.com/cb

③、授权做事器验证成功后,授权做事器将通报一个授权码到资源做事器,如下:

https://myredirecturi.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

④、资源做事器利用吸收到的授权码(code),调用授权做事器的接口,获取访问令牌(access token),如下:

如果调用成功,将返回如下数据:

2、简化模式(implicit)

简化模式(implicit grant type)不通过第三方运用程序的做事器,直接在浏览器中向认证做事器申请令牌,跳过了\"大众授权码\"大众这个步骤,因此得名。
所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不须要认证。

详细实现如下:

①、在创建做事器时,只需配置做事器以许可简化模式。
如下:

这许可授权掌握器直接从要求返回访问令牌到做事器的授权端点。

②、当利用简化模式时,访问令牌将被授权掌握器检索。
客户端通过在OAuth做事器的“授权”端点中设置查询字符串参数response_type = token来指定授权类型。

当用户访问资源做事器时,我们将其导引到授权做事器,如下:

https://api.mysite.com/authorize?response_type=token&client_id=TestClient&redirect_uri=https://myredirecturi.com/cb

③、授权做事器验证成功后,授权做事器将通报一个访问令牌到资源做事器,如下:

https://myredirecturi.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=bearer&expires_in=3600

3、密码模式(resource owner password credentials)

密码模式中,用户向客户端供应自己的用户名和密码。
客户端利用这些信息,向\"大众做事商供应商\"大众索要授权。

在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。
这常日用在用户对客户端高度信赖的情形下,比如客户端是操作系统的一部分,或者由一个著名公司出品。
而认证做事器只有在其他授权模式无法实行的情形下,才能考虑利用这种模式。

详细实现如下:

①、创建一个OAuth2 \ GrantType \ UserCredentials的实例并将其添加到您的做事器

把稳:用户存储对付每个运用程序都是高度自定义的,以是强烈建议您利用OAuth2 \ Storage \ UserCredentialsInterface来实现自己的存储。

②、直接发送用户凭据来获取访问令牌

如果您的客户端是公共的(默认情形下,当客户端没有与此干系的秘钥时是这样的),则可以省略要求中的client_secret值:

③、当相应成功时,将返回访问令牌(access token),如下:

4、客户端模式(client credentials)

客户端模式指客户端以自己的名义,而不因此用户的名义,向\"大众做事供应商\"大众进行认证。
严格地说,客户端模式并不属于OAuth框架所要办理的问题。
在这种模式中,用户直接向客户端注册,客户端以自己的名义哀求\公众做事供应商\公众供应做事,实在不存在授权问题。

详细实现如下:

①、创建一个OAuth2 \ GrantType \ ClientCredentials的实例并将其添加到您的做事器

②、配置参数

客户端模式具有以下配置:

allow_credentials_in_request_body

除了授权HTTP头之外,是否在POST主体中查找凭据。
默认值:true

③、调用接口获取访问令牌(access token)

调用成功时,返回如下数据:

补充拓展

通过上面的先容,大家该当基本清楚了Oauth2的利用了。
下面作为扩展内容,大家可以选择利用。

一、授权模式

除了上面先容的四种模式之外,该库还是实现了其余两种模式:刷新令牌模式(Refresh Token)和JWT Bearer模式。

1、刷新令牌(Refresh Token)

刷新令牌模式用于获取额外的访问令牌,以延长客户端对用户资源的授权。

详细实现如下:

①、创建一个OAuth2 \ GrantType \ RefreshToken的实例并将其添加到您的做事器

把稳:

只有在利用授权码模式或密码模式检索令牌时才供应刷新令牌。

如果将实现OAuth2 \ Storage \ RefreshTokenInterface的存储供应给您的OAuth2 \ Server实例,则只会返回刷新令牌。

②、配置参数

刷新令牌模型具有以下配置:

always_issue_new_refresh_token

是否在成功的令牌要求时发出新的刷新令牌。
默认:false

访问令牌返回类型具有以下配置:

refresh_token_lifetime

刷新令牌到期之前的韶光。
默认:1209600(14天)

但是,当利用做事器的配置数组创建做事器时,可以发送这两个配置选项:

③、刷新令牌

利用授权码模式或密码模式检索令牌:

如果实行成功,将返回如下数据:

刷新令牌可以用来天生一个即是或小于范围的新访问令牌:

如果实行成功,将返回如下数据:

如果做事器配置为同时获取令牌和刷新令牌,那么刷新令牌也会随着此相应返回:

2、JWT Bearer

JWT Bearer模式用于客户端希望吸收访问令牌而不传输敏感信息(如客户端密钥)的情形。
这也可以与受信赖的客户端一起利用,以在没有用户授权的情形下访问用户资源。

详细实现如下:

①、创建OAuth2 \ GrantType \ JwtBearer的实例并将其添加到您的做事器

JWT要求须要利用公钥加密技能来签署JWT声明。
下面的代码片段供应了一个如何完成的例子。

把稳:本示例利用此库中供应的OAuth2 \ Encryption \ Jwt类。
这对付JWT身份验证不是必需的,但是方便。

②、然后可以调用该函数来为要求天生负载。
编写脚本来天生jwt并要求令牌:

实行成功,将返回如下数据:

二、授权范围(scope)

在OAuth2运用程序中利用授权范围(scope)常日是精确容许的关键。
授权范围(scope)用于资源所有者限定对客户的授权。
如:Facebook用户向客户授权各种不同功能的能力(“访问基本信息”,“贴在墙上”等)。

在这个库中,授权范围(scope)是通过实现OAuth2 \ Storage \ ScopeInterface来处理的。
可以利用您自己的实现或利用现有的OAuth2 \ Storage \ Memory类来完成:

这是最大略的方法,但范围也可以动态配置:

此示例假定正在利用的类实现OAuth2 \ Storage \ ScopeInterface:

验证授权范围

在做事器类中配置授权范围(scope)将确保客户端要求的授权范围(scope)是有效的。
但是,要确保精确验证授权范围(scope),须要实行两个步骤。

首先,要求的授权范围(scope)必须在授权的情形下暴露给资源所有者。
在这个库中,这个被实现了100%。
用户界面或必须清楚授权的范围。

其次,资源要求本身必须指定访问它所需的授权范围(scope)

自定义授权范围

由于每个运用程序的授权范围(scope)的实现可能会有很大差异,因此供应除OAuth2 \ Scope以外的其他种别可能会有所帮助。
在自定义类中实现OAuth2 \ ScopeInterface以完备自定义。

state状态参数默认是授权重定向所必需的。
这相称于一个CSRF令牌,并为您的授官僚求供应会话验证。
这是为了安全目的而默认启用的,但是当你配置你的做事器时你可以删除这个需求

利用多个范围

您可以通过在授官僚求中供应以空格分隔(但是网址安全)的浸染域列表来要求多个浸染域。
它看起来像这样:

这将创建一个具有以下四个范围的授权代码:“onescope”,“twoscope”,“redscope”和“bluescope”,然后利用OAuth2 \ ScopeUtil类对这些范围进行验证,以确保它们存在。
如果您收到缺点invalid_scope:要求不支持的浸染域,这是由于您须要在做事器工具上设置可用的浸染域,如下所示:

限定客户端访问范围

客户端可用的范围由客户端存储中的浸染域字段和浸染域存储中定义的可用浸染域列表的组合来掌握。
当客户端有一个配置的范围列表时,客户端被限定为仅利用那些范围。
当没有配置范围时,客户端可以利用的范围不受限定,它可以利用授权做事器内可用的所有范围。

三、User IDs

将本地用户与访问令牌干系联

一旦你对一个用户进行了认证并发布了一个访问令牌(比如一个授权掌握器),那么你可能想知道当访问令牌被利用时哪个用户被运用。
您可以通过利用handleAuthorizeRequest的可选user_id参数来实行此操作:

这将利用访问令牌将用户标识保存到数据库中。
当令牌被客户端利用时,您可以检索关联的ID:

参考地址:https://bshaffer.github.io/oauth2-server-php-docs