8. Laravel5学习笔记:在laravel5中使用OAuth授权

原创 2015年07月09日 19:16:09

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.phpproviders 数组增加服务提供者
LucaDegasperi\OAuth2Server\Storage\FluentStorageServiceProvider::class,
LucaDegasperi\OAuth2Server\OAuth2ServerServiceProvider::class,
// viewForm表单使用,与OAuth无直接关系,只是为了布局方便
Illuminate\Html\HtmlServiceProvider::class,
  • config/app.phpaliases 数组增加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 = [
        // 注释掉
        //\App\Http\Middleware\VerifyCsrfToken::class,
        \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 grantImplicit grantResource owner credentials grantClient 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提供的路由缓存功能。
整个路由代码如下:

// 这是需要经过OAuth2.0授权后才能访问的资源,不信你直接访问绝对会报错
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(){
    // display a form where the user can authorize the client to access it's data
    $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']]);
}]);
// 用户通过授权,客户端向认证服务器申请令牌的HTTP请求
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 the user has allowed the client to access its data, redirect back to the client with an auth code
    if (Input::get('approve') !== null) {
        $redirectUri = Authorizer::issueAuthCode('user', $params['user_id'], $params);
    }

    // if the user has denied the client to access its data, redirect back to the client with an error message
    if (Input::get('deny') !== null) {
        $redirectUri = Authorizer::authCodeRequestDeniedRedirectUri();
    }

    return Redirect::to($redirectUri);
}]);
// 认证服务器发送的HTTP回复
Route::post('oauth/access_token', ['as' => 'access_token', function() {
    header('Content-Type:application/json; charset=utf-8');
    return Response::json(Authorizer::issueAccessToken());
}]);
// 用来客户端向认证服务器申请令牌的HTTP请求的页面,便于发送post请求
Route::get('/callback', function(){
    if(Input::has('code')){
        return view('callback');
    }
});

以上使用到的视图文件,请参考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,到这里就讲完了!希望对你有帮助。


Laravel5专题目录

版权声明:本文为博主原创文章,未经博主允许不得转载。

Laravel5框架使用Oauth2.0

Laravel5:一款享誉国内外的PHP框架。 Oauth2.0 : 一款耳熟能详的作为令牌验证机制的开源软件。 为什么会将这两者搭配起来? 主要的动机是我需要做一个Android客户端,这必然涉...

基于API的用户认证(OAuth2.0,JWT(json web token))了解

1.OAuth2.0 API接口权限认证OAuth2.0流程(用户访问客户端并将其导向认证服务器->用户授权->认证服务器将用户导向客服端redirectURL并附带授权code->客户端将code...

Laravel chmod(/var/dev/project/storage/oauth-public.key):操作失败:不允许操作

在更新了以下软件包后,我发现无法找到oauth-public.key文件。 包装操作:1次安装,2次更新,0次清除 更新laravel /框架(v5.4.27 => v5.4.28):...

Laravel 生成key

php artisan key:generate
  • chenlix
  • chenlix
  • 2016年01月29日 10:28
  • 4427

实现OAuth2.0服务端【授权码模式(Authorization Code)】

要实现OAuth服务端,就得先理解客户端的调用流程,服务提供商实现可能也有些区别,实现OAuth服务端的方式很多,具体可能看http://oauth.net/code/ 各语言的实现有(我使...

通过OAuth2.0方式弹出授权页面获得用户基本信息

获取微信用户的个人的信息的时候,要特别注意的是有两个不同的Access Token,他们产生的方式不一样,一种是使用AppID和AppSecret获取的access_token,一种是OAuth2...

spring Security4 和 oauth2整合 注解+xml混合使用(授权码篇)

Spring Security4 和 oauth2整合授权码模式上两篇介绍了环境配置和用户密码模式,下面介绍授权码模式。...

基于OAUTH2的统一认证的实例解析

非常感谢 http://www.imooc.com/article/10931 在一个单位中,可能是存在多个不同的应用,比如学校会有财务的系统会有学生工作的系统,还有图书馆的系统等等...

Laravel如何引用第三方(自定义)库

想做一个网页抓取的功能,底层使用php的laravel框架。 这里使用phpQuery库来实现网页抓取,这里不做介绍。 需要了解的可以百度,或者等我填坑。 下载最新版本可以前往https://code...
  • IROYCN
  • IROYCN
  • 2015年07月24日 10:23
  • 15879

Auth2.0原理

Auth2.0授权认证流程
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:8. Laravel5学习笔记:在laravel5中使用OAuth授权
举报原因:
原因补充:

(最多只允许输入30个字)