初めに
laravelを触り始めて2月ほど経ちますが、
ここ数日 Passportを触ってみて面倒だな。と感じたことを残しておきます。
作成されるクライアントのIDが整数
phpmyadminで確認すると、IDがintでした。
シーケンス番号であれば問題ないのですが、実際に使用する際はIDを指定するので、intは困る。
google,facebookなどのSNSログインを実装すると知るのですが、client_idは英数字の羅列です。
ドキュメント記載のphp artisan passport:install --uuids
を実行するとユニークなIDを持ったテーブルを再構築できます。
しかし、この後 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句の使い方]
(https://public-constructor.com/laravel-query-builder-where-clauses/#toc2)
[Laravel SQLの実行クエリログを出力する > コンソール画面で表示できました。]
(https://qiita.com/ucan-lab/items/753cb9d3e4ceeb245341)