OAuth2.0简介
关于它的介绍,给出以下两篇文章,相信看完,应该对它有一定程度的了解:
[1] 理解OAuth 2.0 —— 阮一峰
[2] 帮你深入理解OAuth2.0协议 —— seccloud
这里我主要阐述的是在laravel5中使用OAuth2.0。关于这个协议本身,以及运行流程希望大家看完以上两篇文章,理解后,再看我后面的内容!
Laravel5中安装OAuth2.0
OAuth2.0在官方中提供了 php的库 ,但是我们这里并不直接使用它官方提供的 Server Libraries ,我们使用github上 oauth2-server-laravel 这个库,它是经过改造,适合 Laravel5
的(Laravel4的安装就选对版本)。
使用教程
其实关于如何使用这个包,在 oauth2-server-laravel
提供的项目已经说得很清楚了,但是文档首先是英文的不便于只管理解,然后有几个小坑,这里用中文转述及补全一下:
安装
首先要用它,就需要先安好它。由于目前Laravel5的稳定版还没有发布,只提供了开发版(这里按照github上的文档安装会出错就是由于提供的版本还没有发布,需要使用开发版),所有安装如下:
"lucadegasperi/oauth2-server-laravel": "~4.1@dev",
"illuminate/html": "~5.0"
ps:这里安装 illuminate/html
是由于从Laravel5开始这个包就被移除了,然后我们项目中需要使用它,但是它并不是必须的,你可以选择不安装,不安装你在页面中将不能使用 {!! Form::hidden('client_id', $params['client_id']) !!}
这种操作。
配置
配置完全可以按照提供的文档来,步骤如下:
- 向
config/app.php
的 providers
数组增加服务提供者
LucaDegasperi\OAuth2Server\Storage\FluentStorageServiceProvider::class,
LucaDegasperi\OAuth2Server\OAuth2ServerServiceProvider::class,
// view中Form表单使用,与OAuth无直接关系,只是为了布局方便
Illuminate\Html\HtmlServiceProvider::class,
- 向
config/app.php
的 aliases
数组增加Facades
'Authorizer'=> LucaDegasperi\OAuth2Server\Facades\Authorizer::class,
// 与OAuth2.0认证无直接关系,只是为了方便布局使用
'Form' => Illuminate\Html\FormFacade::class,
'HTML' => Illuminate\Html\HtmlFacade::class,
- 修改
app/Http/Kernel.php
,配置相关的中间件
protected $middleware = [
\LucaDegasperi\OAuth2Server\Middleware\OAuthExceptionHandlerMiddleware::class,
];
protected $routeMiddleware = [
// 增加以下路由,原先的保留
'oauth' => \LucaDegasperi\OAuth2Server\Middleware\OAuthMiddleware::class,
'oauth-owner' => \LucaDegasperi\OAuth2Server\Middleware\OAuthOwnerMiddleware::class,
'check-authorization-params' => \LucaDegasperi\OAuth2Server\Middleware\CheckAuthCodeRequestMiddleware::class,
'csrf' => \App\Http\Middleware\VerifyCsrfToken::class,
];
执行 PHP artisan vendor:publish
生成相关的配置文件,你在 config
会看到生成了一个 oauth2.php
文件。
在数据库中生成OAuth2.0需要的数据库表,只需要执行 php artisan migrate
即可,你会在数据库中看到以下表的生成:
选择客户端的授权模式,OAuth2.0有四种模式,分别是:Authorisation code grant
、 Implicit grant
、 Resource owner credentials grant
、 Client credentials grant
。这里我就介绍微博使用的 Authorisation code grant
该模式,相信大家一通百通。
选择后,首选要在 config/oauth2.php
中配置 grant_types
选项:
'grant_types' => [
'authorization_code' => [
'class' => '\League\OAuth2\Server\Grant\AuthCodeGrant',
'access_token_ttl' => 3600,
'auth_token_ttl' => 3660
]
]
代码与数据库的处理
数据库初始化数据
在写代码之前,我们先来把数据库里边填入一些初始数据。
首先是增加一个用户,推荐大家使用 Laravel5
自带的 Seeder
来完成。我就不说过程了,直接告诉大家该初始化一些什么数据!
* 向 users
table添加一个用户
* 向 oauth_clients
table 添加一个client,需要注意的是它的id是字符串类型,相当于申请微博时分配的AppKey
* 向 oauth_scopes
table添加两天记录,如下图:
* 向 oauth_client_scopes
table中添加记录如下:
* 向 oauth_client_endpoints
添加记录如图:
ps:此处应该注意,redirect_uri
的值应该是填写你自己本地能够回调的地址,不要一味模仿,请根据自己的实际情况
至于添加这些数据到底是神马意思,相信根据表的命名可以猜出一二,是在不清楚的可以留言询问哈。
终于到了代码阶段
这里为了简便,我将所有代码按照github上提供的文档,卸载了路由文件中,建议项目中使用时,请将闭包中的代码移植到控制器中,否则你将无法使用laravel提供的路由缓存功能。
整个路由代码如下:
Route::get('/', ['middleware' => ['oauth'], function () {
return view('welcome');
}]);
Route::get('auth/login', function() {
return view('auth.login');
});
Route::post('auth/login', function()
{
if(Auth::attempt(Input::only('email', 'password'))){
return Redirect::intended('oauth');
}
});
Route::get('oauth/authorize', ['as' => 'oauth.authorize.get', 'middleware' => ['check-authorization-params', 'auth'], function(){
$authParams = Authorizer::getAuthCodeRequestParams();
$formParams = array_except($authParams,'client');
$formParams['client_id'] = $authParams['client']->getId();
return View::make('oauth.authorization-form', ['params'=>$formParams,'client'=>$authParams['client']]);
}]);
Route::post('oauth/authorize', ['as' => 'oauth.authorize.post','middleware' => ['csrf', 'check-authorization-params', 'auth'], function() {
$params = Authorizer::getAuthCodeRequestParams();
$params['user_id'] = Auth::user()->id;
$redirectUri = '';
if (Input::get('approve') !== null) {
$redirectUri = Authorizer::issueAuthCode('user', $params['user_id'], $params);
}
if (Input::get('deny') !== null) {
$redirectUri = Authorizer::authCodeRequestDeniedRedirectUri();
}
return Redirect::to($redirectUri);
}]);
Route::post('oauth/access_token', ['as' => 'access_token', function() {
header('Content-Type:application/json; charset=utf-8');
return Response::json(Authorizer::issueAccessToken());
}]);
Route::get('/callback', function(){
if(Input::has('code')){
return view('callback');
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
以上使用到的视图文件,请参考Laravle-OAuth2项目。
效果展示
这里页面效果的演示,我会按照OAuth2.0的执行过程来进行说明,先将 授权码模式 的执行流程帖在这里:
中文解释如下:
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
对应A步骤:
A步骤中,客户端申请认证的URI,包含以下参数:
redirect_uri:表示重定向URI,可选项
state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
response_type:表示授权类型,必选项,此处的值固定为”code”
client_id:表示客户端的ID,必选项
scope:表示申请的权限范围,可选项
对应B步骤:
通过A步骤访问后,显示的页面就是把是否授权展现给了用户,用户可以进行选择,假设用户选择 Approve
,那么继续
对应C步骤:
这时候观察地址栏发现地址栏中显示的地址是我们的回调地址,以及携带了code及state的参数。观察控制台也会发现302的状态码。
对应D步骤:
本身来说这一步是不可见的,对于用户,但是为了演示,所以提供了这样一个post表单,正常项目中大家可以通过客户端后台向AS发送认证的post请求,此时AS会返回一个json数据,从中取出 access_token
后,附加在相关的资源URI后面,即可访问该资源了。
对应E步骤:
获取服务器返回数据
{
"access_token":"Zv0anjwEjAm7SFZGjH1K3MRW6yNj56SuC5MGI9kB",
"token_type":"Bearer",
"expires_in":3600
}
OK,现在可以测试访问需要授权的资源了。针对于我们这里就是:
http://localhost/llaravel/public/ ,此时如果不添加参数,直接访问会看到以下报错信息:
{
"error":"invalid_request",
"error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \"access token\" parameter."
}
正确的访问姿势是:http://localhost/llaravel/public?access_token=Zv0anjwEjAm7SFZGjH1K3MRW6yNj56SuC5MGI9kB,此时访问,你就会看到Laravel5漂亮的首页界面了。
OK,到这里就讲完了!希望对你有帮助。
来自 http://blog.csdn.net/hel12he/article/details/46820711