0
0

More than 1 year has passed since last update.

Laravel PassportでOAuth2を用いた認証機能を作成しよう!④

Last updated at Posted at 2023-08-18

はじめに

本記事は Laravel Passport で OAuth2 を用いた認証機能を作成する手順の一部です。
事前にこちらの記事からご覧ください。

※ 太字の部分が本記事で説明している内容です。

【リソースサーバ 兼 認証サーバ】
1. Laravel Passport のインストール
2. Laravel Passport の初期設定
3. ログイン画面の作成
4. マイページ画面の作成
5. ユーザ情報確認/更新画面の作成
6. ログアウト処理の追加

【クライアントアプリ】
7. トークンのリクエスト処理の追加
8. Laravel Sanctum の初期設定
9. ログインユーザ情報表示画面の作成
10. ログアウト処理の追加

【リソースサーバ 兼 認証サーバ】
11. Laravel Passport のルート登録
12. トークン取消 API の作成

作成手順

本記事ではリソースサーバ 兼 認証サーバを完成させて、最終的な動作確認まで行っていきます。

11. Laravel Passport のルート登録

Laravel Passport のデフォルトで登録されるルートを無視する設定を行っているため、本手順で必要なルートを登録します。

routes\web.php
Route::get('/logout', [App\Http\Controllers\AuthController::class, 'logout']);

+ Route::group([
+   'as' => 'passport.',
+   'prefix' => config('passport.path', 'oauth'),
+   'namespace' => '\Laravel\Passport\Http\Controllers',
+ ], function () {
+   Route::get('/authorize', [
+       'uses' => 'AuthorizationController@authorize',
+       'as' => 'authorizations.authorize',
+       'middleware' => 'web',
+   ]);
+   Route::post('/token', [
+       'uses' => 'AccessTokenController@issueToken',
+       'as' => 'token',
+       'middleware' => 'throttle',
+   ]);
+ });

また、/oauth/token ルートに関しては POST でのリクエストとなるため、VerifyCsrfToken ミドルウェアのチェックに引っかかってしまいます。そこで特例として /oauth/token だけは除外するように追記します。

app\Http\Middleware\VerifyCsrfToken.php
protected $except = [
-   //
+   '/oauth/token',
];

12. トークン取消 API の作成

AuthController にトークン取消処理を追加します。処理内容は以下の通りです。

  1. oauth_access_tokens テーブルから user_idclient_id が一致する使用可能なトークンの id を取得する。
  2. id が一致するアクセストークンを使用不可に更新する。
  3. id が一致するリフレッシュトークンを使用不可に更新する。
app\Http\Controllers\AuthController.php
+   public function revokeToken(Request $request, string $clientId): JsonResponse
+   {
+       $tokenIds = Passport::token()
+           ->where('user_id', Auth::id())
+           ->where('client_id', $clientId)
+           ->where('revoked', false)
+           ->get()
+           ->pluck('id');
+
+       Passport::token()
+           ->whereIn('id', $tokenIds)
+           ->update(['revoked' => true]);
+
+       Passport::refreshToken()
+           ->whereIn('access_token_id', $tokenIds)
+           ->update(['revoked' => true]);
+
+       return response()->json();
+   }

作成したトークン取消処理にアクセスするルートを登録します。

routes\api.php
- Route::middleware('auth:api')->get('/user', function (Request $request) {
-   return $request->user();
+ Route::middleware('auth:api')->group(function () {
+   Route::get('/user', fn (Request $request) => $request->user());
+   Route::delete('/token/{clientId}', [\App\Http\Controllers\AuthController::class, 'revokeToken']);
});

動作確認

すべての手順が完了したので、実際に Authorization Code Grant を用いた認証を試してみます。

まずは、各プロジェクトで以下のコマンドを実行して、開発用サーバを起動します。

リソースサーバ 兼 認証サーバ

npm run build
php artisan serve --port=8080

クライアントアプリ

npm run build
php artisan serve

サーバを起動したら、http://localhost:8000 にアクセスします。アクセスすると未認証の状態でログインユーザ確認画面が表示されるので、「ログイン」をクリックします。

クリックすると以下の順序でリダイレクトが行われ、ログイン画面が表示されます。

http://localhost:8000/auth/redirect
 → http://localhost:8080/oauth/authorize
 → http://localhost:8080/login

メールアドレスとパスワードを入力して「ログインする」をクリックすると以下の順序でリダイレクトが行われ、認証済みの状態で最初に表示したログインユーザ確認画面が表示されます。

http://localhost:8080/login
 → http://localhost:8080/oauth/authorize
 → http://localhost:8000/auth/callback
 → http://localhost:8000

ログイン処理と同様に「ログアウト」をクリックすると以下の順序でリダイレクトが行われ、未認証の状態でログインユーザ確認画面が表示されます。

http://localhost:8000/logout
 → http://localhost:8080/logout
 → http://localhost:8000

以上で動作確認は完了です。
リソースサーバ 兼 認証サーバに登録されたユーザを用いて、クライアントアプリで認証を行うことができました。

0
0
1

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
0
0