Laravel Passportの使い方:インストールからOAuth2 API認証の実装まで徹底解説

実装・応用テクニック

Laravel Passportは、OAuth2サーバーを迅速に構築できる公式パッケージです。「トークンを使ったAPI認証を実装したいが、Sanctumとどちらを使えばいいのかわからない」「昔の記事の通りにPassport::routes()を書いたらエラーになった」という声も多く、パッケージのバージョンによって手順が変わりやすい分野でもあります。この記事では、実際にLaravel 13 + Passport 13系の環境でインストールから動作確認まで検証したうえで、最新の実装手順を解説します。

Laravel Passportとは?

Laravel Passportは、OAuth2の仕様に準拠した認証サーバーをLaravelアプリケーションに組み込むための公式パッケージです。アクセストークンの発行・失効・スコープ管理、認可コードグラントやクライアントクレデンシャルグラントといった複数の認可フローを、自前で実装することなく利用できます。

主に次のようなケースで選ばれます。

  • 自社のAPIを第三者の外部アプリケーションに公開し、OAuth2の「認可」フローで連携させたい
  • スマートフォンアプリやIoTデバイスなど、複数のクライアント種別ごとに異なる認可フローを使い分けたい
  • アクセストークンにスコープ(権限範囲)を持たせて、細かくアクセス制御したい

Laravel SanctumとPassportの使い分け

Laravelには軽量なAPIトークン認証パッケージ「Laravel Sanctum」も用意されており、どちらを使うべきか迷いやすいポイントです。判断基準は次の通りです。

要件 選ぶべきパッケージ
自社SPA・モバイルアプリ向けのシンプルなトークン認証だけでよい Sanctum
OAuth2の認可コードグラント・PKCE・スコープなど、フル機能のOAuth2サーバーが必要 Passport
第三者の外部サービスに自社APIへのアクセスを許可したい(サードパーティ連携) Passport
導入・運用をできるだけシンプルにしたい Sanctum

公式ドキュメントでも「OAuth2への完全準拠が必要な場合のみPassportを選び、それ以外はSanctumで十分」と案内されています。まずは要件を整理し、単純なトークン認証で足りるならSanctumを検討してください。

動作要件

  • PHP 8.2以上
  • Laravel 11以上
  • Composerが利用できる環境

本記事の検証は、composer create-project laravel/laravelで作成したLaravel 13.20.0(PHP 8.3)+ Laravel Passport 13.7.5の組み合わせで行っています。

Laravel Passportのインストール

まずComposerでパッケージを追加します。

composer require laravel/passport

インストール後、Artisanコマンドを実行してAPI認証のスキャフォールディングを行います。以前のバージョンではphp artisan passport:installを直接叩く手順が主流でしたが、現行版ではinstall:apiコマンドに--passportオプションを付けて実行するのが推奨手順です(install:apiコマンドの詳細はこちら)。

php artisan install:api --passport

このコマンドを実行すると、実機検証では次の処理が自動的に行われました。

  • OAuth関連のマイグレーションファイル(oauth_clientsoauth_access_tokensなど5テーブル)が生成され、その場でmigrateまで自動実行される(別途php artisan migrateを打つ必要はありません)
  • 暗号化キーが生成される
  • 「Laravel」という名前のパーソナルアクセストークン用クライアントが自動作成される
  • routes/api.phpに、auth:apiミドルウェアで保護された/userエンドポイントが追加される

実行後、次のような案内が表示されます。

INFO  Published API routes file.
INFO  API scaffolding installed. Please add the [Laravel\Passport\HasApiTokens] trait to your User model.

Userモデルの設定

案内の通り、App\Models\UserHasApiTokensトレイトを追加します。あわせて、現行版ではLaravel\Passport\Contracts\OAuthenticatableインターフェイスの実装も必要です。

use Laravel\Passport\Contracts\OAuthenticatable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable implements OAuthenticatable
{
    use HasApiTokens, Notifiable;

    // ...
}

認証ガードの設定

install:api --passportを実行しただけでは、config/auth.phpapiガードは追加されません。この状態で保護ルートにアクセスすると、実機検証で次のエラーが発生しました。

{
    "message": "Auth guard [api] is not defined.",
    "exception": "InvalidArgumentException"
}

config/auth.phpguardsに、ドライバをpassportとしたapiガードを追加してください。

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

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

なお、Laravel 10以前の記事でよく見かけるAuthServiceProviderでのPassport::routes()の呼び出しは、現行のPassportには存在しないメソッドです。OAuth関連のルート(/oauth/tokenなど)はPassportのサービスプロバイダによって自動登録されるため、記述すると呼び出しエラーになります。古い記事を参考にする際は注意してください。

トークンの発行と保護ルートへのアクセス

ここまでの設定で、認証済みユーザーはアクセストークンを発行できます。createTokenメソッドでパーソナルアクセストークンを発行するコード例です。

$user = User::find(1);
$token = $user->createToken('MyApp')->accessToken;

発行したトークンを使って、実際に保護ルート(GET /api/user)へアクセスできることを検証しました。

curl -H "Accept: application/json" \
     -H "Authorization: Bearer {発行したトークン}" \
     http://localhost:8000/api/user
{
    "id": 1,
    "name": "Ms. Icie Adams",
    "email": "test@example.com",
    "email_verified_at": "2026-07-21T02:54:34.000000Z",
    "created_at": "2026-07-21T02:54:35.000000Z",
    "updated_at": "2026-07-21T02:54:35.000000Z"
}

トークンを付けずにAccept: application/jsonヘッダーのみでアクセスすると、次の401レスポンスが返ることも確認済みです。

{"message":"Unauthenticated."}

OAuth2のグラントタイプ一覧

Passportは複数の認可フロー(グラントタイプ)に対応しています。用途に応じて使い分けます。

グラントタイプ 用途 既定で有効か
パーソナルアクセストークン 自社サーバーからAPIを叩く、テスト用トークン発行 有効
認可コードグラント(PKCE対応) 第三者アプリにユーザーの許可を得てAPIアクセスを許可する、標準的なOAuth2フロー 有効
クライアントクレデンシャルグラント ユーザーを介さないマシン間通信(バッチ処理・スケジュールジョブなど) 有効
デバイス認証グラント スマートTVやCLIツールなど、ブラウザを直接操作できない機器の認証 有効
パスワードグラント ファーストパーティのモバイルアプリでメールアドレスとパスワードから直接トークン発行 無効(要オプトイン)
暗黙的グラント JavaScriptクライアントへの直接トークン発行(非推奨のレガシー方式) 無効(要オプトイン)

実機検証では、パスワードグラントと暗黙的グラントはセキュリティ上の理由から既定で無効になっていることを確認しました。利用する場合はAppServiceProviderbootメソッドで明示的に有効化します。

use Laravel\Passport\Passport;

public function boot(): void
{
    Passport::enablePasswordGrant();
}

クライアントクレデンシャルグラント用のクライアントは、次のコマンドで作成できます。

php artisan passport:client --client --name="Client Credentials Client"
INFO  New client created successfully.

Client ID ..... 019f8299-1dbc-7353-8ec2-e5977f6734b8
Client Secret . 33p0l5Glve6bryjtF0JYRL17OtAkm8TQZTma7cIf

WARN  The client secret will not be shown again, so don't lose it!

トークンの有効期限を設定する

Passportの既定では、アクセストークン・リフレッシュトークン・パーソナルアクセストークンのいずれも有効期限は1年です。セキュリティを高めるため、AppServiceProviderbootメソッドで短めに設定することを推奨します。

use Carbon\Carbon;
use Laravel\Passport\Passport;

public function boot(): void
{
    Passport::tokensExpireIn(Carbon::now()->addDays(15));
    Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
    Passport::personalAccessTokensExpireIn(Carbon::now()->addMonths(6));
}

よくあるエラーと対処法

エラー・症状 原因 対処法
Auth guard [api] is not defined. config/auth.phpapiガードが未定義 本記事の「認証ガードの設定」の通り、driver: passportapiガードを追加する
Route [login] not defined. APIリクエストなのにAccept: application/jsonヘッダーが無く、未認証時にログイン画面へリダイレクトしようとしている APIクライアント側で必ずAccept: application/jsonを付ける
Call to undefined method Passport::routes() 現行のPassportに存在しない古い記述をそのまま使っている Passport::routes()の呼び出しを削除する(現行版は自動登録のため不要)
ユーザーモデルでエラーになる HasApiTokensトレイトまたはOAuthenticatableインターフェイスの実装漏れ Userモデルに両方を追加する

まとめ

Laravel Passportは、OAuth2に完全準拠したAPI認証をLaravelアプリケーションに組み込める公式パッケージです。現行版のポイントは、php artisan install:api --passportでマイグレーションまで一括実行される一方、apiガードの追加とUserモデルへのトレイト・インターフェイス実装は手動で行う必要がある点、そして旧バージョンで必須だったPassport::routes()の呼び出しがすでに廃止されている点です。単純なトークン認証で十分な場合は、より軽量なLaravel Sanctumの利用も検討してください。APIエンドポイント全般の設計についてはLaravel API開発の基礎から応用までもあわせて参考にしてください。

よくある質問

Q. Laravel PassportとLaravel Sanctumはどちらを使うべきですか?

A. 自社SPAやモバイルアプリ向けのシンプルなトークン認証であればSanctum、第三者アプリへのAPI公開やOAuth2の認可コードグラント・スコープ管理が必要な場合はPassportを選びます。

Q. 古い記事にあるphp artisan passport:installやPassport::routes()は使えますか?

A. passport:installコマンド自体は現行版にも残っていますが、現行のLaravelではphp artisan install:api --passportを使うのが公式の推奨手順です。またPassport::routes()は現行のPassportクラスから削除されており、記述するとエラーになります。

Q. パスワードグラントが使えないのですが?

A. パスワードグラントと暗黙的グラントはセキュリティ上の理由から既定で無効化されています。AppServiceProviderbootメソッドでPassport::enablePasswordGrant()を呼び出すことで有効化できます。

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする

コメント