寻找Laravel 5.2 OAuth2实施的从头到尾的操作方法

jre*_*kes 1 authentication rest oauth oauth-2.0 laravel-5

快速背景:我对PHP很有经验,但需要构建我的第一个RESTful API.我想我会尝试Laravel(5.2)并开始觉得很舒服.

我开始在周末为我的项目添加auth,我真的很难让它工作.我得到了基本的Laravel Auth中间件快速工作,但我认为我需要使用OAuth2进行生产(我将构建一个将连接到此服务器的移动应用程序).我正在使用Luca Degasperi OAuth2软件包,它看起来很受欢迎.

我查看了实际文档:https://github.com/lucadegasperi/oauth2-server-laravel/tree/master/docs#readme)

我还浏览了这个教程:https://medium.com/@mshanak/laravel-5-token-based-authentication-ae258c12cfea#.5lszb67xb

而且,最近,我发现这个线程有关在任何工作之前播种OAuth表的必要性:https://github.com/lucadegasperi/oauth2-server-laravel/issues/56

这一切都很棒,但最近Laravel的分布存在一些细微差别.例如,/ app/Http/Kernel.php与我发现的一些示例中显示的略有不同,因为它现在使用中间件组.我以为我正确处理了这些差异(我将OAuthExceptionHandlerMiddleware类添加到$ middlewareGroups的'web'部分而不是$ middleware).我让我的播种机工作了(目前的oauth_scopes表只允许你提供描述,所以我不得不减少上面第三个链接提供的内容).

如果我在routes.php的'web'组中放置测试路径,我会认为这需要OAuth,因为我将OAuth添加到Kernel.php中的'web'中间件组.事实并非如此.如果我这样做,我的路线无需验证.

然后我明确地将OAuth中间件添加到我的测试路由中,如下所示:

Route::get('tests/events', ['middleware' => 'oauth', function() {
    $events = App\Event::get();
    return response()->json($events);
}]);
Run Code Online (Sandbox Code Playgroud)

这导致500错误("OAuth2ServerServiceProvider.php第126行中的ErrorException:explode()期望参数2为字符串,对象给定").

我感到非常迷茫.这些软件包中的每一个似乎都变得如此之快,以至于没有关于如何启动和运行的完整文档.

我还需要做些什么来实现这个功能?

jre*_*kes 6

以下链接最终让我解开了:

https://github.com/lucadegasperi/oauth2-server-laravel/blob/master/docs/authorization-server/password.md

现在我已经开始工作了,我会尝试将它作为完整的密码类型.我没有玩其他授权类型.因此,假设您正在构建类似RESTful API的内容,用户将使用您要构建的客户端应用程序连接到该API.因此,用户将在您的系统中创建用户帐户,然后当他们发送REST请求时,OAuth2包将对其进行身份验证并向他们发送令牌以保持登录状态.

我正在使用Laravel 5.2并且已经启动并运行了基本的Auth包.请注意,即使使用Laravel或OAuth2软件包的增量版本,许多这些步骤似乎也会发生变化.


获得这项工作的第一部分已经很好地记录了(https://github.com/lucadegasperi/oauth2-server-laravel/tree/master/docs#readme),但这里是一个总结,以防万一......

编辑文件的require部分composer.json看起来像这样:

"require": {
    "php": ">=5.5.9",
    "laravel/framework": "5.2.*",
    "lucadegasperi/oauth2-server-laravel": "5.1.*"
},
Run Code Online (Sandbox Code Playgroud)

运行composer update以下载包.

打开config/app.php文件并将以下两行添加到该providers部分的末尾:

LucaDegasperi\OAuth2Server\Storage\FluentStorageServiceProvider::class,
LucaDegasperi\OAuth2Server\OAuth2ServerServiceProvider::class,
Run Code Online (Sandbox Code Playgroud)

同样config/app.php,将此行添加到aliases数组中:

'Authorizer' => LucaDegasperi\OAuth2Server\Facades\Authorizer::class,
Run Code Online (Sandbox Code Playgroud)

现在我们开始做一些与文档略有不同的事情,以适应当前版本的Laravel ...

打开app/Http/Kernel.php.Laravel现在使用组,它不习惯.更新你$middlewareGroups的样子如下:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,

        //Added for OAuth2 Server
        \LucaDegasperi\OAuth2Server\Middleware\OAuthExceptionHandlerMiddleware::class,

        //Commented out for OAuth2 Server
        //\App\Http\Middleware\VerifyCsrfToken::class,
    ],

    'api' => [
        'throttle:60,1',
    ],
];
Run Code Online (Sandbox Code Playgroud)

同样在app/Http/kernel.php,更新$routeMiddleware看起来像这样:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,

    //Added for OAuth2 Server
    'oauth' => \LucaDegasperi\OAuth2Server\Middleware\OAuthMiddleware::class,
    'oauth-user' => \LucaDegasperi\OAuth2Server\Middleware\OAuthUserOwnerMiddleware::class,
    'oauth-client' => \LucaDegasperi\OAuth2Server\Middleware\OAuthClientOwnerMiddleware::class,
    'check-authorization-params' => \LucaDegasperi\OAuth2Server\Middleware\CheckAuthCodeRequestMiddleware::class,
    'csrf' => App\Http\Middleware\VerifyCsrfToken::class,
];
Run Code Online (Sandbox Code Playgroud)

您现在必须设置您的授权类型.你过去常常在一个地方config\oauth2.php使用带闭包的数组callback.使用最新版本的OAuth2服务器软件包,您不能再使用闭包callback.它必须是一个字符串.所以你grant_types应该看起来像这样:

'grant_types' => [
    'password' => [
        'class' => '\League\OAuth2\Server\Grant\PasswordGrant',
        'callback' => '\App\PasswordGrantVerifier@verify',
        'access_token_ttl' => 3600
    ]
]
Run Code Online (Sandbox Code Playgroud)

access_token_ttl是一个身份验证令牌的持续时间(以秒为单位).主程序包文档默认使用3600(1小时).您可能想要尝试604800(1周) - 至少在测试期间.

您现在需要创建刚才在上面的代码部分中调用的PasswordGrantVerifier类和verify方法.因此,您创建一个文件App/PasswordGrantVerifier.php并使用以下代码(这基本上是在闭包中使用的代码callback).

<?php

namespace App;

use Illuminate\Support\Facades\Auth;

class PasswordGrantVerifier
{
    public function verify($username, $password)
    {
        $credentials = [
            'email'    => $username,
            'password' => $password,
        ];

        if (Auth::once($credentials)) {
            return Auth::user()->id;
        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

oauth_clients在OAuth2工作之前,您需要在表格中至少有一行.您可以手动插入内容或创建播种器.要创建播种器,请修改database/seeds/DatabaseSeeder.php并将以下内容添加到run()方法的末尾:

$this->call(OAuthClientsTableSeeder::class);
Run Code Online (Sandbox Code Playgroud)

现在创建一个名为的文件database/seeds/OAuthClientsTableSeeder.php并输入如下内容:

<?php

use Illuminate\Database\Seeder;

class OAuthClientsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //Add sample users
        $oAuthClients = array(
            array(
                'id' => 'TEST_ENVIRONMENT',
                'secret' => 'b17b0ec30dbb6e1726a17972afad008be6a3e4a5',
                'name' => 'TEST_ENVIRONMENT'
            )
        );

        foreach ($oAuthClients as $oAuthClient) {
            App\OAuthClient::create($oAuthClient);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

运行php artisan vendor:publish以发布程序包配置和迁移.运行php artisan migrate以设置OAuth的十亿左右新表.运行php artisan db:seed以播种数据库.

您现在可以在中设置一些测试路线app\Http\routes.php.他们应该看起来像这样:

Route::post('oauth/access_token', function() {
    return Response::json(Authorizer::issueAccessToken());
});

Route::group(['middleware' => 'oauth'], function () {

    Route::get('authroute', function() {
        //OAuth will be required to access this route
    });

    Route::post('postwithauth', function(Request $request) {
        $userID = Authorizer::getResourceOwnerId();
        $input = $request->input();
        return response()->json(array('userID' => $userID, 'input' => $input));
    });

});

Route::get('noauthroute', function () {
    //No authorization will be required to access this route
});
Run Code Online (Sandbox Code Playgroud)

密切关注postwithauth上面包含的路线.OAuth2包最近改变了您访问用户ID的方式,我花了很长时间才弄明白如何获取它.

现在是时候进行测试了,将浏览器指向localhost:8000(或者测试环境的路径)并为自己创建一个用户帐户(此步骤只使用标准的Laravel Auth软件包).

进入你的HTTP客户端(我现在正在使用Paw,我喜欢它).转到请求 - >授权 - > OAuth2以设置您要测试的路由的授权.对于Grant Type,选择Resource Owner Password Credentials.如果您使用我上面提供的种子例如,Client IDTEST_ENVIRONMENTClient Secret就是b17b0ec30dbb6e1726a17972afad008be6a3e4a5,输入您通过网络验证界面创建的用户名(电子邮件)和密码,你Access Toekn URL将会像localhost:8000/oauth/access_token(取决于你如何设置你的测试环境),离开Scope空白,Token应该说Bearer.单击Get Access Token然后Use Access Token在出现提示时说出.

那应该是它!