nomadnt/lumen-passport

Laravel Passport 的 Lumen 版本

v10.1.0 2021-01-01 22:27 UTC

This package is auto-updated.

Last update: 2024-09-29 05:08:36 UTC


README

Total Downloads Latest Stable Version License

Lumen Passport

Laravel Passport 的 Lumen 版本。灵感来源于 https://github.com/dusterio/lumen-passport,但尽量使其与原始 Laravel Passport 保持透明

依赖

  • PHP >= 7.3.0
  • Lumen >= 8.0

安装

首先,如果您还没有安装 Lumen 框架,请先安装它。

composer create-project --prefer-dist laravel/lumen lumen-app && cd lumen-app

然后安装 Lumen Passport(它将一起获取 Laravel Passport)

composer require nomadnt/lumen-passport

配置

生成您的 APP_KEY 并使用单条命令更新 .env 文件

sed -i "s|\(APP_KEY=\)\(.*\)|\1$(openssl rand -base64 24)|" .env

配置您的数据库连接(例如,使用 SQLite)。更改后,您的 .env 文件应该看起来像这样

APP_NAME=Lumen
APP_ENV=local
APP_KEY=<my-super-strong-api-key>
APP_DEBUG=true
APP_URL=https://:8000
APP_TIMEZONE=UTC

LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=

DB_CONNECTION=sqlite

CACHE_DRIVER=file
QUEUE_CONNECTION=sync

将 Lumen 配置文件夹复制到您的项目中

cp -a vendor/laravel/lumen-framework/config config

更新您的 config/auth.php 文件中的 guardsproviders 部分,以匹配 Passport 的要求

<?php

return [
    ...

    'guards' => [
        'api' => ['driver' => 'passport', 'provider' => 'users']
    ],

    ...

    'providers' => [
        'users' => ['driver' => 'eloquent', 'model' => \App\Models\User::class]
    ]

    ...
];

您需要修改 bootstrap/app.php 文件,如下所示

<?php

...

// enable facades
$app->withFacades();

// enable eloquent
$app->withEloquent();

...

$app->configure('app');

// initialize auth configuration
$app->configure('auth');

...

// enable auth and throttle middleware
$app->routeMiddleware([
    'auth'     => App\Http\Middleware\Authenticate::class,
    'throttle' => Nomadnt\LumenPassport\Middleware\ThrottleRequests::class
]);

...

// register required service providers

// $app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
$app->register(Laravel\Passport\PassportServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);

...

创建 database.sqlite

touch database/database.sqlite

启动迁移

php artisan migrate

安装 Laravel passport

# Install encryption keys and other necessary stuff for Passport
php artisan passport:install

之前的命令应该返回类似于以下内容的输出

Encryption keys generated successfully.
Personal access client created successfully.
Client ID: 1
Client secret: BxSueZnqimNTE0r98a0Egysq0qnonwkWDUl0KmE5
Password grant client created successfully.
Client ID: 2
Client secret: VFWuiJXTJhjb46Y04llOQqSd3kP3goqDLvVIkcIu

注册路由

现在,是时候注册必要的 passport 路由,以颁发访问令牌和撤销访问令牌、客户端和个人访问令牌了。
为此,打开您的 app/Providers/AuthServiceProvider.php 文件,并将 boot 函数修改为以下示例所示。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Carbon;

// don't forget to include Passport
use Nomadnt\LumenPassport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        // 
    }

    /**
     * Boot the authentication services for the application.
     *
     * @return void
     */
    public function boot()
    {
        // register passport routes
        Passport::routes();

        // change the default token expiration
        Passport::tokensExpireIn(Carbon::now()->addDays(15));

        // change the default refresh token expiration
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
    }
}

用户模型

确保您的用户模型使用了 Passport 的 HasApiTokens 特性,例如。

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Laravel\Passport\HasApiTokens;
use Laravel\Lumen\Auth\Authorizable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;

class User extends Model implements AuthenticatableContract, AuthorizableContract
{
    use HasApiTokens, Authenticatable, Authorizable;

    // rest of the model
}

访问令牌事件

修剪和/或撤销令牌

如果您想基于事件撤销或清除令牌,您必须创建相关监听器并在您的 app/Http/Providers/EventServiceProvider.php 中注册,而不是使用已弃用的属性 Passport::$revokeOtherTokens = true;Passport::$pruneRevokedTokens = true;

首先,请确保 EventServiceProvider 已在您的 bootstrap/app.php 中注册

<?php

...

// $app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
$app->register(Laravel\Passport\PassportServiceProvider::class);
$app->register(App\Providers\EventServiceProvider::class);

...

然后,您需要监听 AccessTokenCreated 事件并注册所需的监听器

<?php

namespace App\Providers;

use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider{

    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'Laravel\Passport\Events\AccessTokenCreated' => [
            'App\Listeners\RevokeOtherTokens',
            'App\Listeners\PruneRevokedTokens',
        ]
    ];
}

创建 app/Listeners/RevokeOtherTokens.php 文件并将以下内容放入其中

<?php

namespace App\Listeners;

use Laravel\Passport\Events\AccessTokenCreated;
use Laravel\Passport\Token;

class RevokeOtherTokens
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  \App\Events\OrderShipped  $event
     * @return void
     */
    public function handle(AccessTokenCreated $event)
    {
        Token::where(function($query) use($event){
            $query->where('user_id', $event->userId);
            $query->where('id', '<>', $event->tokenId);
        })->revoke();
    }
}

创建 app/Listeners/PruneRevokedTokens.php 文件并将以下内容放入其中

<?php

namespace App\Listeners;

use Laravel\Passport\Events\AccessTokenCreated;
use Laravel\Passport\Token;

class PruneRevokedTokens
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  \App\Events\AccessTokenCreated  $event
     * @return void
     */
    public function handle(AccessTokenCreated $event)
    {
        Token::where(function($query) use($event){
            $query->where('user_id', $event->userId);
            $query->where('id', '<>', $event->tokenId);
            $query->where('revoked', true);
        })->delete();
    }
}