LoginSignup
2
1

More than 1 year has passed since last update.

laravel8 Passport 調査して不思議に感じたこと

Last updated at Posted at 2021-10-11

初めに

laravelを触り始めて2月ほど経ちますが、
ここ数日 Passportを触ってみて面倒だな。と感じたことを残しておきます。

作成されるクライアントのIDが整数

phpmyadminで確認すると、IDがintでした。
シーケンス番号であれば問題ないのですが、実際に使用する際はIDを指定するので、intは困る。
google,facebookなどのSNSログインを実装すると知るのですが、client_idは英数字の羅列です。

ドキュメント記載のphp artisan passport:install --uuidsを実行するとユニークなIDを持ったテーブルを再構築できます。
スクリーンショット 2021-10-11 14.36.11.png

しかし、この後 php artisan passport:installを実行すると
IDにデフォルト値がないとエラーが発生します。
どうやらコマンド実行時に使用されるメソッドは ユニークなIDを発行する機能が存在しません。
今回は直接passportライブラリに追記します。

//ClientRepository.php
public function create($userId, $name, $redirect, $provider = null, $personalAccess = false, $password = false, $confidential = true)
    {
        $client = Passport::client()->forceFill([
            'id' => (string) Str::orderedUuid(), //idにuuidを付与
            'user_id' => $userId,
            'name' => $name,
            'secret' => ($confidential || $personalAccess) ? Str::random(40) : null,
            'provider' => $provider,
            'redirect' => $redirect,
            'personal_access_client' => $personalAccess,
            'password_client' => $password,
            'revoked' => false,
        ]);

        $client->save();
}

再度コマンド実行することでクライアントを作成できます。


Which user ID should the client be assigned to?:
 > 

 What should we name the client?:
 > ******

 Where should we redirect the request after authorization? [http://localhost:8080/auth/callback]:
 > http:localhost:3000/callback.php

New client created successfully.
Here is your new client secret. This is the only time it will be shown so don't lose it!

Client ID: **********************************
Client secret: **********************************

使用しないルーティングを消すのが面倒だった。

複数の認証方法が使用できる為、RouteRegistrar.phpにルーティングが用意されています。
しかし、不要なルーティングの除外は設定として存在しません。

今回は、Passport.php RouteRegisterを上書きするディレクトリ[packages]を用意、
Composerに追記し、 dump-autoroadを実行し、
app/Providers/AuthServiceProvider に カスタマイズしたrouteを読み込みました。

//composer.jsonに追記
"autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/",
            "Custom\\": "packages/"   //追加
        }
    },

修正後、 composer dump-autoload を実行し useで読み込めるようにする

他の方がルートを限定する書き方公開されていました。

こちらのほうが楽です。
公開するルートを限定する

用意されているPurgeコマンドが使いづらい。

  • 無効・期限切れのトークンと認可コードを破棄する
  • 無効なトークンと認可コードのみ破棄する
  • 期限切れのトークンと認可コードのみ破棄する

と用意されています。
しかし期限切れのトークンを削除するには、有効期限から本日から7日前を経過する必要があリました。
幅を持たせる為に7日前超過にしてるんですかね?
でも、発行されたexpired_atをwhereで検索するので、そこまで幅を持たせる必要があるのかな...

ドキュメント記載の有効期限を AuthServiceProvider::boot() 内に
Passport::tokensExpireIn(now()->addMinutes(60));
を記載して変更しても実際のデータはしばらく残ります。

実際の運用状況で変わるかと思いますが、
config/passport.phpなどで柔軟に対応して欲しいです。
しかし、リフレッシュトークンからアクセストークンを再発行できるのでこのPurgeコマンドもどう使えばいいか悩みますね。

php artisan passport:purgeコマンド実行時のコード

//PurgeCommand.php
public function handle()
    {
        $expired = Carbon::now()->subDays(7);

        if (($this->option('revoked') && $this->option('expired')) ||
            (! $this->option('revoked') && ! $this->option('expired'))) {
            Passport::token()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
            Passport::authCode()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
            Passport::refreshToken()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();

            $this->info('Purged revoked items and items expired for more than seven days.');
        } elseif ($this->option('revoked')) {
            Passport::token()->where('revoked', 1)->delete();
            Passport::authCode()->where('revoked', 1)->delete();
            Passport::refreshToken()->where('revoked', 1)->delete();

            $this->info('Purged revoked items.');
        } elseif ($this->option('expired')) {
            Passport::token()->whereDate('expires_at', '<', $expired)->delete();
            Passport::authCode()->whereDate('expires_at', '<', $expired)->delete();
            Passport::refreshToken()->whereDate('expires_at', '<', $expired)->delete();

            $this->info('Purged items expired for more than seven days.');
        }
    }

※whereDate()は日付単位での検索になるので、 where()を使用すると分単位で指定できました。

 終わり

まだ、触ると疑問が出てきますが一旦これで終了します。
Laravel Passportを実際に使用しているサービスってあるんですかね。
ドキュメントだけでは少し不安です。

今回、参考にさせていただいた記事

Laravel Passportの使い方まとめ
Query Builder(クエリビルダー) – 各種where句の使い方
Laravel SQLの実行クエリログを出力する > コンソール画面で表示できました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1