Readouble

Laravel 12.x Laravel Passport

イントロダクションIntroduction

Laravel Passportは、Laravelアプリケーションへ完全なOAuth2サーバの実装を数分で提供します。Passportは、Andy MillingtonとSimon HampがメンテナンスしているLeague OAuth2 serverの上に構築しています。Laravel Passport[https://github.com/laravel/passport] provides a full OAuth2 server implementation for your Laravel application in a matter of minutes. Passport is built on top of the League OAuth2 server[https://github.com/thephpleague/oauth2-server] that is maintained by Andy Millington and Simon Hamp.

note Note: このドキュメントは、皆さんがOAuth2に慣れていることを前提にしています。OAuth2について知らなければ、この先を続けて読む前に、一般的な用語とOAuth2の機能について予習してください。[!NOTE] This documentation assumes you are already familiar with OAuth2. If you do not know anything about OAuth2, consider familiarizing yourself with the general terminology[https://oauth2.thephpleague.com/terminology/] and features of OAuth2 before continuing.

Passportか?Sanctumか??Passport or Sanctum?

始める前に、アプリケーションがLaravel Passport、もしくはLaravel Sanctumのどちらにより適しているかを検討することをお勧めします。アプリケーションが絶対にOAuth2をサポートする必要がある場合は、Laravel Passportを使用する必要があります。Before getting started, you may wish to determine if your application would be better served by Laravel Passport or Laravel Sanctum[/docs/{{version}}/sanctum]. If your application absolutely needs to support OAuth2, then you should use Laravel Passport.

しかし、シングルページアプリケーションやモバイルアプリケーションを認証したり、APIトークンを発行したりする場合は、Laravel Sanctumを使用する必要があります。Laravel SanctumはOAuth2をサポートしていません。ただし、はるかにシンプルなAPI認証開発エクスペリエンスを提供します。However, if you are attempting to authenticate a single-page application, mobile application, or issue API tokens, you should use Laravel Sanctum[/docs/{{version}}/sanctum]. Laravel Sanctum does not support OAuth2; however, it provides a much simpler API authentication development experience.

インストールInstallation

Laravel Passportは、install:api Artisanコマンドでインストールします。You may install Laravel Passport via the install:api Artisan command:

php artisan install:api --passport

このコマンドは、アプリケーションがOAuth2クライアントとアクセストークンを格納するために必要なテーブルを作成するために必要なデータベースのマイグレーションをリソース公開し、実行します。このコマンドは、セキュアなアクセストークンを生成するために必要な暗号化キーも作成します。This command will publish and run the database migrations necessary for creating the tables your application needs to store OAuth2 clients and access tokens. The command will also create the encryption keys required to generate secure access tokens.

install:apiコマンドを実行したら、App\Models\UserモデルへLaravel\Passport\HasApiTokensトレイトとLaravel\Passport\Contracts\OAuthenticatableインターフェイスを追加してください。このトレイトは、認証済みユーザーのトークンとスコープを検査できる、いくつかのヘルパメソッドをモデルに提供します。After running the install:api command, add the Laravel\Passport\HasApiTokens trait and Laravel\Passport\Contracts\OAuthenticatable interface to your App\Models\User model. This trait will provide a few helper methods to your model which allow you to inspect the authenticated user's token and scopes:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\Contracts\OAuthenticatable;
use Laravel\Passport\HasApiTokens;

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

最後に、アプリケーションのconfig/auth.php設定ファイルで、api認証ガードを定義して、driverオプションをpassportに設定します。これにより、API リクエストを認証する際に PassportのTokenGuardを使用するようアプリケーションに指示します。Finally, in your application's config/auth.php configuration file, you should define an api authentication guard and set the driver option to passport. This will instruct your application to use Passport's TokenGuard when authenticating incoming API requests:

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

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

PassportのデプロイDeploying Passport

Passportをアプリケーションのサーバへ初めてデプロイするときは、passport:keysコマンドを実行する必要があります。このコマンドは、アクセストークンを生成するためにPassportが必要とする暗号化キーを生成します。生成されたキーは通常、ソース管理しません。When deploying Passport to your application's servers for the first time, you will likely need to run the passport:keys command. This command generates the encryption keys Passport needs in order to generate access tokens. The generated keys are not typically kept in source control:

php artisan passport:keys

必要であれば、Passportのキーをロードするパスを定義することもできます。これにはPassport::loadKeysFromメソッドを使用します。通常、このメソッドはアプリケーションのApp\Providers\AppServiceProviderクラスの bootメソッドから呼び出します。If necessary, you may define the path where Passport's keys should be loaded from. You may use the Passport::loadKeysFrom method to accomplish this. Typically, this method should be called from the boot method of your application's App\Providers\AppServiceProvider class:

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    Passport::loadKeysFrom(__DIR__.'/../secrets/oauth');
}

環境からのキーのロードLoading Keys From the Environment

または、vendor:publish Artisanコマンドを使用してPassportの設定ファイルをリソース公開することもできます。Alternatively, you may publish Passport's configuration file using the vendor:publish Artisan command:

php artisan vendor:publish --tag=passport-config

設定ファイルをリソース公開した後、環境変数として定義することにより、アプリケーションの暗号化キーをロードできます。After the configuration file has been published, you may load your application's encryption keys by defining them as environment variables:

PASSPORT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
<プライベートキーをここに記述>
-----END RSA PRIVATE KEY-----"

PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
<パブリックキーをここに記述>
-----END PUBLIC KEY-----"

PassportのアップグレードUpgrading Passport

Passportの新しいメジャーバージョンにアップグレードするときは、アップグレードガイドを注意深く確認することが重要です。When upgrading to a new major version of Passport, it's important that you carefully review the upgrade guide[https://github.com/laravel/passport/blob/master/UPGRADE.md].

設定Configuration

トークン持続時間Token Lifetimes

Passportはデフォルトで、1年後に失効する長寿命のアクセストークンを発行します。トークンの有効期限を長く/短く設定したい場合は、tokensExpireInrefreshTokensExpireInpersonalAccessTokensExpireInメソッを使用してください。これらのメソッドは、アプリケーションの App\Providers\AppServiceProviderクラスのbootメソッドから呼び出す必要があります。By default, Passport issues long-lived access tokens that expire after one year. If you would like to configure a longer / shorter token lifetime, you may use the tokensExpireIn, refreshTokensExpireIn, and personalAccessTokensExpireIn methods. These methods should be called from the boot method of your application's App\Providers\AppServiceProvider class:

use Carbon\CarbonInterval;

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    Passport::tokensExpireIn(CarbonInterval::days(15));
    Passport::refreshTokensExpireIn(CarbonInterval::days(30));
    Passport::personalAccessTokensExpireIn(CarbonInterval::months(6));
}

warning Warning! Passportのデータベーステーブルのexpires_atカラムは読み取り専用であり、表示のみを目的としています。トークンを発行するとき、Passportは署名および暗号化されたトークン内に有効期限情報を保存します。トークンを無効にする必要がある場合は、取り消す必要があります。[!WARNING] The expires_at columns on Passport's database tables are read-only and for display purposes only. When issuing tokens, Passport stores the expiration information within the signed and encrypted tokens. If you need to invalidate a token you should revoke it[#revoking-tokens].

デフォルトモデルのオーバーライドOverriding Default Models

独自のモデルを定義し、対応するPassportモデルを拡張することにより、Passportにより内部的に使用されるモデルを自由に拡張できます。You are free to extend the models used internally by Passport by defining your own model and extending the corresponding Passport model:

use Laravel\Passport\Client as PassportClient;

class Client extends PassportClient
{
    // ...
}

モデルを定義した後、Laravel\Passport\Passportクラスを使い、カスタムモデルを使うようにPassportへ指示できます。通常、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドで、カスタムモデルについてPassportへ通知します。After defining your model, you may instruct Passport to use your custom model via the Laravel\Passport\Passport class. Typically, you should inform Passport about your custom models in the boot method of your application's App\Providers\AppServiceProvider class:

use App\Models\Passport\AuthCode;
use App\Models\Passport\Client;
use App\Models\Passport\DeviceCode;
use App\Models\Passport\RefreshToken;
use App\Models\Passport\Token;

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    Passport::useTokenModel(Token::class);
    Passport::useRefreshTokenModel(RefreshToken::class);
    Passport::useAuthCodeModel(AuthCode::class);
    Passport::useClientModel(Client::class);
    Passport::useDeviceCodeModel(DeviceCode::class)
}

ルートのオーバーライドOverriding Routes

Passportが定義するルートをカスタマイズしたい場合もあるでしょう。そのためには、まずアプリケーションのAppServiceProviderregisterメソッドへ、Passport::ignoreRoutesを追加し、Passportが登録したルートを無視する必要があります。Sometimes you may wish to customize the routes defined by Passport. To achieve this, you first need to ignore the routes registered by Passport by adding Passport::ignoreRoutes to the register method of your application's AppServiceProvider:

use Laravel\Passport\Passport;

/**
 * 全アプリケーションサービスの登録
 */
public function register(): void
{
    Passport::ignoreRoutes();
}

そして、Passport自身のルートファイルで定義しているルートをアプリケーションのroutes/web.phpファイルへコピーして、好みに合わせ変更してください。Then, you may copy the routes defined by Passport in its routes file[https://github.com/laravel/passport/blob/master/routes/web.php] to your application's routes/web.php file and modify them to your liking:

Route::group([
    'as' => 'passport.',
    'prefix' => config('passport.path', 'oauth'),
    'namespace' => '\Laravel\Passport\Http\Controllers',
], function () {
    // Passportのルート…
});

コードグラントの認証Authorization Code Grant

認証コードを介してOAuth2を使用することは、OAuth2を扱う時にほとんどの開発者が精通している方法です。認証コードを使用する場合、クライアントアプリケーションはユーザーをサーバにリダイレクトし、そこでユーザーはクライアントへアクセストークンを発行するリクエストを承認または拒否します。Using OAuth2 via authorization codes is how most developers are familiar with OAuth2. When using authorization codes, a client application will redirect a user to your server where they will either approve or deny the request to issue an access token to the client.

まず最初に、Passportへ「認証」ビューをどのように返すかを指示する必要があります。To get started, we need to instruct Passport how to return our "authorization" view.

全ての認証ビューのレンダロジックは、Laravel\Passport\Passportクラス経由で、利用可能で適切なメソッドを使ってカスタマイズ可能です。通常、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドからこのメソッドを呼び出します。All the authorization view's rendering logic may be customized using the appropriate methods available via the Laravel\Passport\Passport class. Typically, you should call this method from the boot method of your application's App\Providers\AppServiceProvider class:

use Laravel\Passport\Passport;

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    // ビュー名を指定
    Passport::authorizationView('auth.oauth.authorize');

    // クロージャにより指定
    Passport::authorizationView(fn ($parameters) => Inertia::render('Auth/OAuth/Authorize', [
        'request' => $parameters['request'],
        'authToken' => $parameters['authToken'],
        'client' => $parameters['client'],
        'user' => $parameters['user'],
        'scopes' => $parameters['scopes'],
    ]));
}

Passportはこのビューを返す/oauth/authorizeルートを自動的に定義します。auth.oauth.authorizeテンプレートには、承認を行うためのpassport.authorizations.approveルートへPOSTリクエストを行うフォームと、承認を拒否するためのpassport.authorizations.denyルートへDELETEリクエストを行うフォームを含める必要があります。passport.authorizations.approveルートとpassport.authorizations.denyルートでは、stateclient_idauth_tokenフィールドを期待しています。Passport will automatically define the /oauth/authorize route that returns this view. Your auth.oauth.authorize template should include a form that makes a POST request to the passport.authorizations.approve route to approve the authorization and a form that makes a DELETE request to the passport.authorizations.deny route to deny the authorization. The passport.authorizations.approve and passport.authorizations.deny routes expect state, client_id, and auth_token fields.

クライアントの管理Managing Clients

あなたのアプリケーションのAPIを操作する必要があるアプリケーションを構築する開発者は、「クライアント」を作成することにより、あなたのアプリケーションへ自分のアプリケーションを登録する必要があります。通常、これはアプリケーションの名前と、ユーザーが認証のリクエストを承認した後に、アプリケーションをリダイレクトできるURIを提供してもらうことから構成されます。Developers building applications that need to interact with your application's API will need to register their application with yours by creating a "client". Typically, this consists of providing the name of their application and a URI that your application can redirect to after users approve their request for authorization.

ファーストパーティクライアントFirst-Party Clients

クライアントを作成する一番簡単な方法は、passport:client Artisanコマンドを使用することです。このコマンドは、ファーストパーティクライアントの作成やOAuth2機能のテストに使用します。passport:clientコマンドを実行すると、Passportはクライアントに関する詳細情報を求めるプロンプトを表示し、クライアントIDとシークレットを提供します。The simplest way to create a client is using the passport:client Artisan command. This command may be used to create first-party clients or testing your OAuth2 functionality. When you run the passport:client command, Passport will prompt you for more information about your client and will provide you with a client ID and secret:

php artisan passport:client

クライアントへ複数のリダイレクトURIを許したい場合は、passport:clientコマンドでURIの入力を求められたときに、カンマ区切りのリストを使って指定してください。カンマを含むURIはすべてURIエンコードされている必要があります:If you would like to allow multiple redirect URIs for your client, you may specify them using a comma-delimited list when prompted for the URI by the passport:client command. Any URIs which contain commas should be URI encoded:

https://third-party-app.com/callback,https://example.com/oauth/redirect

サードパーティクライアントThird-Party Clients

アプリケーションのユーザーはpassport:clientコマンドを利用できないため、Laravel\Passport\ClientRepositoryクラスのcreateAuthorizationCodeGrantClientメソッドを使用して、指定ユーザーのクライアントを登録してください。Since your application's users will not be able to utilize the passport:client command, you may use createAuthorizationCodeGrantClient method of the Laravel\Passport\ClientRepository class to register a client for a given user:

use App\Models\User;
use Laravel\Passport\ClientRepository;

$user = User::find($userId);

// 指定ユーザーに属するOAuthアプリクライアントを作成
$client = app(ClientRepository::class)->createAuthorizationCodeGrantClient(
    user: $user,
    name: 'Example App',
    redirectUris: ['https://third-party-app.com/callback'],
    confidential: false,
    enableDeviceFlow: true
);

// ユーザーに属するすべてのOAuthアプリクライアントを取得
$clients = $user->oauthApps()->get();

createAuthorizationCodeGrantClientメソッドはLaravel\Passport\Clientのインスタンスを返します。クライアントIDとして$client->id、クライアント秘密鍵として$client->plainSecretをユーザーへ表示してください。The createAuthorizationCodeGrantClient method returns an instance of Laravel\Passport\Client. You may display the $client->id as the client ID and $client->plainSecret as the client secret to the user.

トークンのリクエストRequesting Tokens

許可のリダイレクトRedirecting for Authorization

クライアントが作成されると、開発者はクライアントIDとシークレットを使用し、あなたのアプリケーションへ許可コードとアクセストークンをリクエストするでしょう。まず、API利用側アプリケーションは以下のように、あなたのアプリケーションの/oauth/authorizeルートへのリダイレクトリクエストを作成する必要があります。Once a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. First, the consuming application should make a redirect request to your application's /oauth/authorize route like so:

use Illuminate\Http\Request;
use Illuminate\Support\Str;

Route::get('/redirect', function (Request $request) {
    $request->session()->put('state', $state = Str::random(40));

    $query = http_build_query([
        'client_id' => 'your-client-id',
        'redirect_uri' => 'https://third-party-app.com/callback',
        'response_type' => 'code',
        'scope' => 'user:read orders:create',
        'state' => $state,
        // 'prompt' => '', // "none", "consent", or "login"
    ]);

    return redirect('https://passport-app.test/oauth/authorize?'.$query);
});

promptパラメータは、Passportアプリケーションの認証動作を指定するために使用します。The prompt parameter may be used to specify the authentication behavior of the Passport application.

promptの値がnoneの場合、ユーザーがPassportアプリケーションで認証されていないとき、Passportは認証エラーを常時スローします。値がconsentの場合、すべてのスコープが事前に利用者側アプリケーションへ許可されていても、Passportは常に承認スクリーンを表示します。値がloginである場合、Passportアプリケーションは、ユーザーが既にセッションを持っていても、アプリケーションへ再ログインするように常に促します。If the prompt value is none, Passport will always throw an authentication error if the user is not already authenticated with the Passport application. If the value is consent, Passport will always display the authorization approval screen, even if all scopes were previously granted to the consuming application. When the value is login, the Passport application will always prompt the user to re-login to the application, even if they already have an existing session.

prompt値を指定しない場合、要求されたスコープに対する消費者側アプリケーションへのアクセスをそのユーザーへ以前に許可していない場合のみ、認可のためのプロンプトを表示します。If no prompt value is provided, the user will be prompted for authorization only if they have not previously authorized access to the consuming application for the requested scopes.

note Note: /oauth/authorizeルートは、すでにPassportが定義づけていることを覚えておいてください。このルートを自分で定義する必要はありません。[!NOTE] Remember, the /oauth/authorize route is already defined by Passport. You do not need to manually define this route.

リクエストの承認Approving the Request

認証リクエストを受け取ると、Passportはpromptパラメータが指定されている場合は、その値に基づいて自動的に応答し、認証リクエストを承認または拒否するためのテンプレートをユーザーに表示します。ユーザーがリクエストを承認した場合、消費者側アプリケーションにより指定された、redirect_uriへリダイレクトします。このredirect_uriは、クライアントが作成されたときに指定した、redirect URLと一致しなければなりません。When receiving authorization requests, Passport will automatically respond based on the value of prompt parameter (if present) and may display a template to the user allowing them to approve or deny the authorization request. If they approve the request, they will be redirected back to the redirect_uri that was specified by the consuming application. The redirect_uri must match the redirect URL that was specified when the client was created.

ファーストパーティクライアントを認証するときなど、認証プロンプトを飛ばしたいことも起きるでしょう。このような場合は、Clientモデルを拡張しskipsAuthorizationメソッドを定義すれば実現できます。skipsAuthorizationが、trueを返したら、クライアントは承認され、ユーザーはすぐにredirect_uriへリダイレクトされます。ただし、消費者側アプリケーションが承認のためのリダイレクト時に、明示的にpromptパラメータを設定した場合はこの限りではありません。Sometimes you may wish to skip the authorization prompt, such as when authorizing a first-party client. You may accomplish this by extending the Client model[#overriding-default-models] and defining a skipsAuthorization method. If skipsAuthorization returns true the client will be approved and the user will be redirected back to the redirect_uri immediately, unless the consuming application has explicitly set the prompt parameter when redirecting for authorization:

<?php

namespace App\Models\Passport;

use Illuminate\Contracts\Auth\Authenticatable;
use Laravel\Passport\Client as BaseClient;

class Client extends BaseClient
{
    /**
     * クライアントが認証プロンプトをスキップするかを決定
     *
     * @param  \Laravel\Passport\Scope[]  $scopes
     */
    public function skipsAuthorization(Authenticatable $user, array $scopes): bool
    {
        return $this->firstParty();
    }
}

許可コードからアクセストークンへの変換Converting Authorization Codes to Access Tokens

ユーザーが承認リクエストを承認すると、ユーザーは利用側アプリケーションにリダイレクトされます。利用側はまず、リダイレクトの前に保存した値に対してstateパラメータを確認する必要があります。状態パラメータが一致する場合、利用側はアプリケーションへPOSTリクエストを発行してアクセストークンをリクエストする必要があります。リクエストには、ユーザーが認証リクエストを承認したときにアプリケーションが発行した認証コードを含める必要があります。If the user approves the authorization request, they will be redirected back to the consuming application. The consumer should first verify the state parameter against the value that was stored prior to the redirect. If the state parameter matches then the consumer should issue a POST request to your application to request an access token. The request should include the authorization code that was issued by your application when the user approved the authorization request:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

Route::get('/callback', function (Request $request) {
    $state = $request->session()->pull('state');

    throw_unless(
        strlen($state) > 0 && $state === $request->state,
        InvalidArgumentException::class,
        'Invalid state value.'
    );

    $response = Http::asForm()->post('https://passport-app.test/oauth/token', [
        'grant_type' => 'authorization_code',
        'client_id' => 'your-client-id',
        'client_secret' => 'your-client-secret',
        'redirect_uri' => 'https://third-party-app.com/callback',
        'code' => $request->code,
    ]);

    return $response->json();
});

この/oauth/tokenルートは、access_tokenrefresh_tokenexpires_in属性を含むJSONレスポンスを返します。expires_in属性は、アクセストークンが無効になるまでの秒数を含んでいます。This /oauth/token route will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.

note Note: /oauth/authorizeルートと同様に、/oauth/tokenルートはPassportによって定義されます。このルートを手作業で定義する必要はありません。[!NOTE] Like the /oauth/authorize route, the /oauth/token route is defined for you by Passport. There is no need to manually define this route.

トークン管理Managing Tokens

ユーザーの認証済みトークンを取得するには、Laravel\Passport\HasApiTokensトレイトのtokensメソッドを使ってください。例えば、サードパーティアプリケーションとの接続を追跡するためのダッシュボードをユーザーに提供するために、これを使うことができるでしょう。You may retrieve user's authorized tokens using the tokens method of the Laravel\Passport\HasApiTokens trait. For example, this may be used to offer your users a dashboard to keep track of their connections with third-party applications:

use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Date;
use Laravel\Passport\Token;

$user = User::find($userId);

// このユーザーの有効なトークンをすべて取得
$tokens = $user->tokens()
    ->where('revoked', false)
    ->where('expires_at', '>', Date::now())
    ->get();

// サードパーティのOAuthアプリクライアントへのユーザーの接続をすべて取得
$connections = $tokens->load('client')
    ->reject(fn (Token $token) => $token->client->firstParty())
    ->groupBy('client_id')
    ->map(fn (Collection $tokens) => [
        'client' => $tokens->first()->client,
        'scopes' => $tokens->pluck('scopes')->flatten()->unique()->values()->all(),
        'tokens_count' => $tokens->count(),
    ])
    ->values();

トークンのリフレッシュRefreshing Tokens

アプリケーションが短期間のアクセストークンを発行する場合、ユーザーはアクセストークンが発行されたときに提供された更新トークンを利用して、アクセストークンを更新する必要があります。If your application issues short-lived access tokens, users will need to refresh their access tokens via the refresh token that was provided to them when the access token was issued:

use Illuminate\Support\Facades\Http;

$response = Http::asForm()->post('https://passport-app.test/oauth/token', [
    'grant_type' => 'refresh_token',
    'refresh_token' => 'the-refresh-token',
    'client_id' => 'your-client-id',
    'client_secret' => 'your-client-secret', // Required for confidential clients only...
    'scope' => 'user:read orders:create',
]);

return $response->json();

この/oauth/tokenルートは、access_tokenrefresh_tokenexpires_in属性を含むJSONレスポンスを返します。expires_in属性は、アクセストークンが無効になるまでの秒数を含んでいます。This /oauth/token route will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.

トークンの取り消しRevoking Tokens

トークンを取り消すには、Laravel\Passport\Tokenモデルのrevokeメソッドを使用します。トークンのリフレッシュトークンを取り消すためには、Laravel\Passport\RefreshTokenモデルのrevoke メソッドを使用します。You may revoke a token by using the revoke method on the Laravel\Passport\Token model. You may revoke a token's refresh token using the revoke method on the Laravel\Passport\RefreshToken model:

use Laravel\Passport\Passport;
use Laravel\Passport\Token;

$token = Passport::token()->find($tokenId);

// アクセストークンの取り消し
$token->revoke();

// リフレッシュトークンの取り消し
$token->refreshToken?->revoke();

// ユーザーのすべてのトークンを取り消し
User::find($userId)->tokens()->each(function (Token $token) {
    $token->revoke();
    $token->refreshToken?->revoke();
});

トークンの削除Purging Tokens

トークンが取り消されたり期限切れになったりした場合は、データベースからトークンを削除することを推奨します。Passportに含まれているpassport:purge Artisanコマンドでこれを実行できます。When tokens have been revoked or expired, you might want to purge them from the database. Passport's included passport:purge Artisan command can do this for you:

# 取り消し・期限切れのトークン、認証コード、デバイスコードを削除
php artisan passport:purge

# 期限切れから6時間以上経っているトークンのみ削除
php artisan passport:purge --hours=6

# 取り消したトークン、認証コード、デバイスコードのみ削除
php artisan passport:purge --revoked

# 期限切れのトークン、認証コード、デバイスコードのみ削除
php artisan passport:purge --expired

アプリケーションのroutes/console.phpファイルでジョブのスケジュールを設定して、このスケジュールに従い自動的にトークンを削除することもできます。You may also configure a scheduled job[/docs/{{version}}/scheduling] in your application's routes/console.php file to automatically prune your tokens on a schedule:

use Illuminate\Support\Facades\Schedule;

Schedule::command('passport:purge')->hourly();

PKCEを使った認可コードグラントAuthorization Code Grant With PKCE

"Proof Key for Code Exchange"(PKCE)を使用した認証コード付与は、シングルページアプリケーションやモバイルアプリケーションがAPIにアクセスする際の安全な認証方法です。このグラントは、クライアントシークレットの機密保存を保証できない場合や、攻撃者による認証コードの傍受の脅威を軽減する場合に使用します。「コードベリファイア」と「コードチャレンジ」の組み合わせは、アクセストークンと認証コードを交換する際に、クライアントシークレットに取って代わるものです。The Authorization Code grant with "Proof Key for Code Exchange" (PKCE) is a secure way to authenticate single page applications or mobile applications to access your API. This grant should be used when you can't guarantee that the client secret will be stored confidentially or in order to mitigate the threat of having the authorization code intercepted by an attacker. A combination of a "code verifier" and a "code challenge" replaces the client secret when exchanging the authorization code for an access token.

クライアント生成Creating the Client

アプリケーションがPKCEでの認証コードグラントを介してトークンを発行する前に、PKCE対応のクライアントを作成する必要があります。これは、passport:client Artisanコマンドと--publicオプションを使用して行えます。Before your application can issue tokens via the authorization code grant with PKCE, you will need to create a PKCE-enabled client. You may do this using the passport:client Artisan command with the --public option:

php artisan passport:client --public

トークンのリクエストRequesting Tokens

コードベリファイヤとコードチャレンジCode Verifier and Code Challenge

この認可グラントではクライアント秘密コードが提供されないため、開発者はトークンを要求するためにコードベリファイヤとコードチャレンジのコンビネーションを生成する必要があります。As this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.

コードベリファイアは、RFC 7636 仕様で定義されているように、文字、数字、"-"".""_""~"文字を含む43文字から128文字のランダムな文字列でなければなりません。The code verifier should be a random string of between 43 and 128 characters containing letters, numbers, and "-", ".", "_", "~" characters, as defined in the RFC 7636 specification[https://tools.ietf.org/html/rfc7636].

コードチャレンジはURL/ファイルネームセーフな文字をBase64エンコードしたものである必要があります。文字列終端の'='文字を削除し、ラインブレイクやホワイトスペースを含まず、その他はそのままにします。The code challenge should be a Base64 encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.

$encoded = base64_encode(hash('sha256', $codeVerifier, true));

$codeChallenge = strtr(rtrim($encoded, '='), '+/', '-_');

許可のリダイレクトRedirecting for Authorization

クライアントが生成できたら、アプリケーションから認可コードとアクセストークンをリクエストするために、クライアントIDと生成したコードベリファイヤ、コードチャレンジを使用します。最初に、認可要求側のアプリケーションは、あなたのアプリケーションの/oauth/authorizeルートへのリダイレクトリクエストを生成する必要があります。Once a client has been created, you may use the client ID and the generated code verifier and code challenge to request an authorization code and access token from your application. First, the consuming application should make a redirect request to your application's /oauth/authorize route:

use Illuminate\Http\Request;
use Illuminate\Support\Str;

Route::get('/redirect', function (Request $request) {
    $request->session()->put('state', $state = Str::random(40));

    $request->session()->put(
        'code_verifier', $codeVerifier = Str::random(128)
    );

    $codeChallenge = strtr(rtrim(
        base64_encode(hash('sha256', $codeVerifier, true))
    , '='), '+/', '-_');

    $query = http_build_query([
        'client_id' => 'your-client-id',
        'redirect_uri' => 'https://third-party-app.com/callback',
        'response_type' => 'code',
        'scope' => 'user:read orders:create',
        'state' => $state,
        'code_challenge' => $codeChallenge,
        'code_challenge_method' => 'S256',
        // 'prompt' => '', // "none"、"consent"、"login"
    ]);

    return redirect('https://passport-app.test/oauth/authorize?'.$query);
});

許可コードからアクセストークンへの変換Converting Authorization Codes to Access Tokens

ユーザーが認可リクエストを承認すると、認可要求側のアプリケーションへリダイレクで戻されます。認可要求側では認可コードグラントの規約に従い、リダイレクトの前に保存しておいた値と、stateパラメータを検証する必要があります。If the user approves the authorization request, they will be redirected back to the consuming application. The consumer should verify the state parameter against the value that was stored prior to the redirect, as in the standard Authorization Code Grant.

stateパラメータが一致したら、要求側はアクセストークンをリクエストするために、あなたのアプリケーションへPOSTリクエストを発行する必要があります。そのリクエストは最初に生成したコードベリファイヤと同時に、ユーザーが認可リクエストを承認したときにあなたのアプリケーションが発行した認可コードを持っている必要があります。If the state parameter matches, the consumer should issue a POST request to your application to request an access token. The request should include the authorization code that was issued by your application when the user approved the authorization request along with the originally generated code verifier:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

Route::get('/callback', function (Request $request) {
    $state = $request->session()->pull('state');

    $codeVerifier = $request->session()->pull('code_verifier');

    throw_unless(
        strlen($state) > 0 && $state === $request->state,
        InvalidArgumentException::class
    );

    $response = Http::asForm()->post('https://passport-app.test/oauth/token', [
        'grant_type' => 'authorization_code',
        'client_id' => 'your-client-id',
        'redirect_uri' => 'https://third-party-app.com/callback',
        'code_verifier' => $codeVerifier,
        'code' => $request->code,
    ]);

    return $response->json();
});

デバイス認証グラントDevice Authorization Grant

OAuth2デバイス認証グラントは、テレビやゲーム機のようなブラウザレスまたは限定された入力デバイスが、「デバイスコード」を交換することでアクセストークンを取得することを可能にします。デバイスフローを使用する場合、デバイスクライアントはユーザーへコンピュータやスマートフォンなどのセカンダリデバイスを使用するよう指示し、提供した「ユーザーコード」を入力してサーバに接続し、アクセス要求を承認または拒否します。The OAuth2 device authorization grant allows browserless or limited input devices, such as TVs and game consoles, to obtain an access token by exchanging a "device code". When using device flow, the device client will instruct the user to use a secondary device, such as a computer or a smartphone and connect to your server where they will enter the provided "user code" and either approve or deny the access request.

これには、まずPassportへ「ユーザーコード」と「認証」ビューをどのように返すかを指示する必要があります。To get started, we need to instruct Passport how to return our "user code" and "authorization" views.

全ての認可ビューのレンダロジックは、Laravel\Passport\Passportクラスで利用可能な、適切なメソッドを使用してカスタマイズできます。通常、アプリケーションのLaravel\Passport\Passportクラスのbootメソッドからこのメソッドを呼び出します。All the authorization view's rendering logic may be customized using the appropriate methods available via the Laravel\Passport\Passport class. Typically, you should call this method from the boot method of your application's App\Providers\AppServiceProvider class.

use Laravel\Passport\Passport;

/**
 * アプリケーションの全サービスの初期起動処理
 */
public function boot(): void
{
    // ビュー名を指定
    Passport::deviceUserCodeView('auth.oauth.device.user-code');
    Passport::deviceAuthorizationView('auth.oauth.device.authorize');

    // クロージャを指定
    Passport::deviceUserCodeView(fn ($parameters) => Inertia::render('Auth/OAuth/Device/UserCode'));

    Passport::deviceAuthorizationView(fn ($parameters) => Inertia::render('Auth/OAuth/Device/Authorize', [
        'request' => $parameters['request'],
        'authToken' => $parameters['authToken'],
        'client' => $parameters['client'],
        'user' => $parameters['user'],
        'scopes' => $parameters['scopes'],
    ]));

    // ...
}

Passportはこれらのビューを返すルートを自動的に定義します。auth.oauth.device.user-codeテンプレートには、passport.device.authorizations.authorizeルートへGETリクエストを行うフォームを含める必要があります。passport.device.authorizations.authorizeルートはuser_codeクエリパラメータを期待しています。Passport will automatically define routes that return these views. Your auth.oauth.device.user-code template should include a form that makes a GET request to the passport.device.authorizations.authorize route. The passport.device.authorizations.authorize route expects a user_code query parameter.

auth.oauth.device.authorizeテンプレートには、承認を行うためのpassport.device.authorizations.approveルートへPOSTリクエストを行うフォームと、承認を拒否するためのpassport.device.authorizations.denyルートへDELETEリクエストを行うフォームを含める必要があります。passport.device.authorizations.approveルートとpassport.device.authorizations.denyルートは、stateclient_idauth_tokenフィールドを必要とします。Your auth.oauth.device.authorize template should include a form that makes a POST request to the passport.device.authorizations.approve route to approve the authorization and a form that makes a DELETE request to the passport.device.authorizations.deny route to deny the authorization. The passport.device.authorizations.approve and passport.device.authorizations.deny routes expect state, client_id, and auth_token fields.

デバイス認証グラントクライアントの作成Creating a Device Authorization Grant Client

アプリケーションがデバイス認証グラントでトークンを発行する前に、デバイスフローが有効なクライアントを作成する必要があります。これを行うには、passport:client Artisanコマンドに--deviceオプションを指定します。このコマンドはファーストパーティのデバイスフロー対応クライアントを作成し、クライアントIDとシークレットを提供します。Before your application can issue tokens via the device authorization grant, you will need to create a device flow enabled client. You may do this using the passport:client Artisan command with the --device option. This command will create a first-party device flow enabled client and provide you with a client ID and secret:

php artisan passport:client --device

さらに、ClientRepositoryクラスのcreateDeviceAuthorizationGrantClientメソッドを使用して、指定ユーザーに属するサードパーティクライアントを登録することもできます。Additionally, you may use createDeviceAuthorizationGrantClient method on the ClientRepository class to register a third-party client that belongs to the given user:

use App\Models\User;
use Laravel\Passport\ClientRepository;

$user = User::find($userId);

$client = app(ClientRepository::class)->createDeviceAuthorizationGrantClient(
    user: $user,
    name: 'Example Device',
    confidential: false,
);

トークンのリクエストRequesting Tokens

デバイスコードのリクエストRequesting a Device Code

クライアントを作成したら、開発者はそのクライアントIDを使用してアプリケーションにデバイスコードをリクエストできます。まず、デバイスコードを要求するためアプリケーションの/oauth/device/codeルートへPOSTリクエストを行います。Once a client has been created, developers may use their client ID to request a device code from your application. First, the consuming device should make a POST request to your application's /oauth/device/code route to request a device code:

use Illuminate\Support\Facades\Http;

$response = Http::asForm()->post('https://passport-app.test/oauth/device/code', [
    'client_id' => 'your-client-id',
    'scope' => 'user:read orders:create',
]);

return $response->json();

これはdevice_codeuser_codeverification_uriintervalexpires_in 属性を含む、JSONレスポンスを返します。expires_in属性には、デバイスコードの有効期限が切れるまでの秒数が格納されます。interval属性には、/oauth/tokenルートをポーリングするときに、レート制限エラーを回避するため、利用するデバイスがリクエスト間で何秒待つかを指定します。This will return a JSON response containing device_code, user_code, verification_uri, interval, and expires_in attributes. The expires_in attribute contains the number of seconds until the device code expires. The interval attribute contains the number of seconds the consuming device should wait between requests when polling /oauth/token route to avoid rate limit errors.

note Note: /oauth/device/codeルートは、あらかじめPassportが定義していることを忘れないでください。このルートを手作業で定義する必要はありません。[!NOTE]
Remember, the /oauth/device/code route is already defined by Passport. You do not need to manually define this route.

確認URIとユーザーコードの表示Displaying the Verification URI and User Code

デバイスコードをリクエストを取得したら、認証要求を承認するため別のデバイスを使用し、指定されたverification_uriへアクセスしてuser_codeを入力するように、消費デバイスでユーザーへ指示してください。Once a device code request has been obtained, the consuming device should instruct the user to use another device and visit the provided verification_uri and enter the user_code in order to approve the authorization request.

トークンリクエストのポーリングPolling Token Request

ユーザーはアクセスを許可(または拒否)するために別のデバイスを使用するので、ユーザーがいつリクエストに応答したかを判断するために、使用デバイスはアプリケーションの/oauth/tokenルートをポーリングする必要があります。使用デバイスは、レートリミットエラーを避けるため、デバイスコードをリクエストするときに、JSONレスポンスで指定される最小のポーリング間隔を使用する必要があります。Since the user will be using a separate device to grant (or deny) access, the consuming device should poll your application's /oauth/token route to determine when the user has responded to the request. The consuming device should use the minimum polling interval provided in the JSON response when requesting device code to avoid rate limit errors:

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Sleep;

$interval = 5;

do {
    Sleep::for($interval)->seconds();

    $response = Http::asForm()->post('https://passport-app.test/oauth/token', [
        'grant_type' => 'urn:ietf:params:oauth:grant-type:device_code',
        'client_id' => 'your-client-id',
        'client_secret' => 'your-client-secret', // 気密性の高いクライアントのみ必須
        'device_code' => 'the-device-code',
    ]);

    if ($response->json('error') === 'slow_down') {
        $interval += 5;
    }
} while (in_array($response->json('error'), ['authorization_pending', 'slow_down']));

return $response->json();

ユーザーが認可リクエストを承認した場合、access_token属性とrefresh_token属性とexpires_in属性を含んだJSONレスポンスが返される。expires_in属性には、アクセストークンの有効期限が切れるまでの秒数が格納されます。If the user has approved the authorization request, this will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.

パスワードグラントPassword Grant

warning Warning! パスワードグラントトークンの使用は、現在推奨していません。代わりに、OAuth2サーバが現在推奨しているグラントタイプ を選択する必要があります。[!WARNING] We no longer recommend using password grant tokens. Instead, you should choose a grant type that is currently recommended by OAuth2 Server[https://oauth2.thephpleague.com/authorization-server/which-grant/].

OAuth2パスワードグラントにより、モバイルアプリケーションなどの他のファーストパーティクライアントは、電子メールアドレス/ユーザー名とパスワードを使用してアクセストークンを取得できます。これにより、ユーザーがOAuth2認証コードのリダイレクトフロー全体を実行しなくても、ファーストパーティクライアントにアクセストークンを安全に発行できます。The OAuth2 password grant allows your other first-party clients, such as a mobile application, to obtain an access token using an email address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire OAuth2 authorization code redirect flow.

パスワードグラントを有効にするには、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドで、enablePasswordGrantメソッドを呼び出してください。To enable the password grant, call the enablePasswordGrant method in the boot method of your application's App\Providers\AppServiceProvider class:

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    Passport::enablePasswordGrant();
}

パスワードグラントクライアントの作成Creating a Password Grant Client

アプリケーションがパスワードグラントでトークンを発行する前に、パスワードグラントクライアントを作成する必要があります。これを行うには、passport:client Artisanコマンドに--passwordオプションを指定します。Before your application can issue tokens via the password grant, you will need to create a password grant client. You may do this using the passport:client Artisan command with the --password option.

php artisan passport:client --password

トークンのリクエストRequesting Tokens

グラントを有効にしてパスワードグラントクライアントを作成したら、ユーザーのメールアドレスとパスワードにより、/oauth/tokenルートへPOSTリクエストを発行し、アクセストークンをリクエストできます。このルートは Passportがあらかじめ登録しているため、手作業で定義する必要はありません。リクエストが成功すると、サーバからのJSONレスポンスに、access_tokenrefresh_tokenが返されます。Once you have enabled the grant and have created a password grant client, you may request an access token by issuing a POST request to the /oauth/token route with the user's email address and password. Remember, this route is already registered by Passport so there is no need to define it manually. If the request is successful, you will receive an access_token and refresh_token in the JSON response from the server:

use Illuminate\Support\Facades\Http;

$response = Http::asForm()->post('https://passport-app.test/oauth/token', [
    'grant_type' => 'password',
    'client_id' => 'your-client-id',
    'client_secret' => 'your-client-secret', // 気密性の高いクライアントのみ必須
    'username' => 'taylor@laravel.com',
    'password' => 'my-password',
    'scope' => 'user:read orders:create',
]);

return $response->json();

note Note: アクセストークンはデフォルトで、長期間有効であることを記憶しておきましょう。ただし、必要であれば自由に、アクセストークンの最長持続時間を設定できます。[!NOTE] Remember, access tokens are long-lived by default. However, you are free to configure your maximum access token lifetime[#configuration] if needed.

全スコープの要求Requesting All Scopes

パスワードグラント、またはクライアント認証情報グラントを使用時は、あなたのアプリケーションでサポートする全スコープを許可するトークンを発行したいと考えるかと思います。*スコープをリクエストすれば可能です。*スコープをリクエストすると、そのトークンインスタンスのcanメソッドは、いつもtrueを返します。このスコープはpasswordclient_credentialsグラントを使って発行されたトークのみに割り付けるのが良いでしょう。When using the password grant or client credentials grant, you may wish to authorize the token for all of the scopes supported by your application. You can do this by requesting the * scope. If you request the * scope, the can method on the token instance will always return true. This scope may only be assigned to a token that is issued using the password or client_credentials grant:

use Illuminate\Support\Facades\Http;

$response = Http::asForm()->post('https://passport-app.test/oauth/token', [
    'grant_type' => 'password',
    'client_id' => 'your-client-id',
    'client_secret' => 'your-client-secret', // 気密性の高いクライアントのみ必須
    'username' => 'taylor@laravel.com',
    'password' => 'my-password',
    'scope' => '*',
]);

ユーザープロバイダのカスタマイズCustomizing the User Provider

アプリケーションが複数の認証ユーザープロバイダを使用している場合、artisan passport:client --passwordコマンドでクライアントを作成するときに、--providerオプションを指定すれば、パスワードグラントクライアントが使用するユーザープロバイダを指定できます。指定するプロバイダ名は、アプリケーションのconfig/auth.php設定ファイルで定義している、有効なプロバイダと一致する必要があります。その後、ミドルウェアを使用してルートを保護することで、ガードの指定したプロバイダからのユーザーのみが認証されるようにすることができます。If your application uses more than one authentication user provider[/docs/{{version}}/authentication#introduction], you may specify which user provider the password grant client uses by providing a --provider option when creating the client via the artisan passport:client --password command. The given provider name should match a valid provider defined in your application's config/auth.php configuration file. You can then protect your route using middleware[#multiple-authentication-guards] to ensure that only users from the guard's specified provider are authorized.

ユーザー名フィールドのカスタマイズCustomizing the Username Field

パスワードグラントを使用して認証する場合、Passportは認証可能なモデルのemail属性を「ユーザー名」として使用します。ただし、モデルでfindForPassportメソッドを定義することにより、この動作をカスタマイズできます。When authenticating using the password grant, Passport will use the email attribute of your authenticatable model as the "username". However, you may customize this behavior by defining a findForPassport method on your model:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

    /**
     * 指定ユーザー名に対応するユーザーインスタンスを検索
     */
    public function findForPassport(string $username): User
    {
        return $this->where('username', $username)->first();
    }
}

パスワードバリデーションのカスタマイズCustomizing the Password Validation

パスワードガードを使用して認証している場合、Passportは指定されたパスワードを確認するためにモデルのpassword属性を使用します。もし、password属性を持っていないか、パスワードのバリデーションロジックをカスタマイズしたい場合は、モデルのvalidateForPassportPasswordGrantメソッドを定義してください。When authenticating using the password grant, Passport will use the password attribute of your model to validate the given password. If your model does not have a password attribute or you wish to customize the password validation logic, you can define a validateForPassportPasswordGrant method on your model:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

    /**
     * Passportパスワードグラントに対しユーザーパスワードを検証
     */
    public function validateForPassportPasswordGrant(string $password): bool
    {
        return Hash::check($password, $this->password);
    }
}

暗黙的グラントImplicit Grant

warning Warning! 暗黙的のグラントトークンの使用は、現在推奨していません。代わりに、OAuth2サーバが現在推奨しているグラントタイプを選択する必要があります。[!WARNING] We no longer recommend using implicit grant tokens. Instead, you should choose a grant type that is currently recommended by OAuth2 Server[https://oauth2.thephpleague.com/authorization-server/which-grant/].

暗黙のグラントは、認証コードグラントと似ていますが、トークンは認証コードを交換せずにクライアントへ返します。このグラントは、JavaScriptやモバイルアプリケーションで、クライアントの認証情報を安全に保存できない場合によく使われます。このグラントを有効にするには、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドでenableImplicitGrantメソッドを呼び出してください。The implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored. To enable the grant, call the enableImplicitGrant method in the boot method of your application's App\Providers\AppServiceProvider class:

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    Passport::enableImplicitGrant();
}

アプリケーションが暗黙的グラントでトークンを発行する前に、暗黙的グラントクライアントを作成する必要があります。これを行うには、passport:client Artisanコマンドに--implicitオプションを指定します。Before your application can issue tokens via the implicit grant, you will need to create an implicit grant client. You may do this using the passport:client Artisan command with the --implicit option.

php artisan passport:client --implicit

グラントを有効にして暗黙的なクライアントを作成すると、開発者はそのクライアントIDを使い、アプリケーションへアクセストークンをリクエストできます。利用するアプリケーションは、あなたのアプリケーションの/oauth/authorizeルートへリダイレクトリクエストを行う必要があります。Once the grant has been enabled and an implicit client has been created, developers may use their client ID to request an access token from your application. The consuming application should make a redirect request to your application's /oauth/authorize route like so:

use Illuminate\Http\Request;

Route::get('/redirect', function (Request $request) {
    $request->session()->put('state', $state = Str::random(40));

    $query = http_build_query([
        'client_id' => 'your-client-id',
        'redirect_uri' => 'https://third-party-app.com/callback',
        'response_type' => 'token',
        'scope' => 'user:read orders:create',
        'state' => $state,
        // 'prompt' => '', // "none"、"consent"、"login"
    ]);

    return redirect('https://passport-app.test/oauth/authorize?'.$query);
});

note Note: /oauth/authorizeルートは、すでにPassportが定義していることを覚えておいてください。このルートを自前で定義する必要はありません。[!NOTE] Remember, the /oauth/authorize route is already defined by Passport. You do not need to manually define this route.

クライアント利用資格情報グラントClient Credentials Grant

クライアント利用資格情報グラントはマシンとマシン間の認証に最適です。たとえば、APIによりメンテナンスタスクを実行する、定期実行ジョブに使用できます。The client credentials grant is suitable for machine-to-machine authentication. For example, you might use this grant in a scheduled job which is performing maintenance tasks over an API.

アプリケーションがクライアント利用資格情報グラントを介してトークンを発行する前に、クライアント利用資格情報グラントクライアントを作成する必要があります。これは、passport:client Artisanコマンドの--clientオプションを使用して行うことができます。Before your application can issue tokens via the client credentials grant, you will need to create a client credentials grant client. You may do this using the --client option of the passport:client Artisan command:

php artisan passport:client --client

次に、Laravel\Passport\Http\Middleware\EnsureClientIsResourceOwnerミドルウェアをルートに割り当てます。Next, assign the Laravel\Passport\Http\Middleware\EnsureClientIsResourceOwner middleware to a route:

use Laravel\Passport\Http\Middleware\EnsureClientIsResourceOwner;

Route::get('/orders', function (Request $request) {
    // アクセストークンは有効で、クライアントはリソースの所有者
})->middleware(EnsureClientIsResourceOwner::class);

ルートへのアクセスを特定のスコープに制限するには、usingメソッドへ必要なスコープのリストを指定します。To restrict access to the route to specific scopes, you may provide a list of the required scopes to the using method`:

Route::get('/orders', function (Request $request) {
    // アクセストークンは有効で、クライアントはリソースの所有者であり、"servers:read"と"servers:create"の両スコープを持っている
})->middleware(EnsureClientIsResourceOwner::using('servers:read', 'servers:create');

トークンの取得Retrieving Tokens

このグラントタイプを使用してトークンを取得するには、oauth/tokenエンドポイントにリクエストを送信します。To retrieve a token using this grant type, make a request to the oauth/token endpoint:

use Illuminate\Support\Facades\Http;

$response = Http::asForm()->post('https://passport-app.test/oauth/token', [
    'grant_type' => 'client_credentials',
    'client_id' => 'your-client-id',
    'client_secret' => 'your-client-secret',
    'scope' => 'servers:read servers:create',
]);

return $response->json()['access_token'];

パーソナルアクセストークンPersonal Access Tokens

ときどき、あなたのユーザーが典型的なコードリダイレクションフローに従うのではなく、自分たち自身でアクセストークンを発行したがることもあるでしょう。あなたのアプリケーションのUIを通じて、ユーザー自身のトークンを発行を許可することにより、あなたのAPIをユーザーに経験してもらう事ができますし、全般的なアクセストークン発行するシンプルなアプローチとしても役立つでしょう。Sometimes, your users may want to issue access tokens to themselves without going through the typical authorization code redirect flow. Allowing users to issue tokens to themselves via your application's UI can be useful for allowing users to experiment with your API or may serve as a simpler approach to issuing access tokens in general.

note Note: もしあなたのアプリケーションが、主にパーソナルアクセストークンを発行するためにPassportを使用しているのであれば、APIアクセストークンを発行するためのLaravelの軽量ファーストパーティライブラリであるLaravel Sanctumの使用を検討してください。[!NOTE] If your application is using Passport primarily to issue personal access tokens, consider using Laravel Sanctum[/docs/{{version}}/sanctum], Laravel's light-weight first-party library for issuing API access tokens.

パーソナルアクセスクライアントの作成Creating a Personal Access Client

アプリケーションがパーソナルアクセストークンを発行する前に、パーソナルアクセスクライアントを作成する必要があります。これを行うには、--personalオプションを指定してpassport:client Artisanコマンドを実行します。すでにpassport:installコマンドを実行している場合は、次のコマンドを実行する必要はありません。Before your application can issue personal access tokens, you will need to create a personal access client. You may do this by executing the passport:client Artisan command with the --personal option. If you have already run the passport:install command, you do not need to run this command:

php artisan passport:client --personal

ユーザープロバイダのカスタマイズCustomizing the User Provider

アプリケーションが複数の認証ユーザープロバイダを使用している場合、artisan passport:client --personalコマンドでクライアントを作成するときに、--providerオプションを指定することで、パーソナルアクセスグラントクライアントが使用するユーザープロバイダを指定できます。指定するプロバイダ名は、アプリケーションのconfig/auth.php設定ファイルで定義している有効なプロバイダと一致させる必要があります。その後、ミドルウェアを使用してルートを保護することで、ガードで指定したプロバイダからのユーザーのみを認証するようにできます。If your application uses more than one authentication user provider[/docs/{{version}}/authentication#introduction], you may specify which user provider the personal access grant client uses by providing a --provider option when creating the client via the artisan passport:client --personal command. The given provider name should match a valid provider defined in your application's config/auth.php configuration file. You can then protect your route using middleware[#multiple-authentication-guards] to ensure that only users from the guard's specified provider are authorized.

パーソナルアクセストークンの管理Managing Personal Access Tokens

パーソナルアクセスクライアントを作成したら、App\Models\UserモデルインスタンスでcreateTokenメソッドを使用して特定のユーザーにトークンを発行できます。createTokenメソッドは、最初の引数にトークン名、2番目の引数にオプションのスコープの配列を取ります。Once you have created a personal access client, you may issue tokens for a given user using the createToken method on the App\Models\User model instance. The createToken method accepts the name of the token as its first argument and an optional array of scopes[#token-scopes] as its second argument:

use App\Models\User;
use Illuminate\Support\Facades\Date;
use Laravel\Passport\Token;

$user = User::find($userId);

// スコープ無しのトークンを作成する
$token = $user->createToken('My Token')->accessToken;

// スコープ付きのトークンを作成する
$token = $user->createToken('My Token', ['user:read', 'orders:create'])->accessToken;

// 全スコープ付きのトークンを作成する
$token = $user->createToken('My Token', ['*'])->accessToken;

// ユーザーに属する有効なパーソナルアクセストークンをすべて取得する。
$tokens = $user->tokens()
    ->with('client')
    ->where('revoked', false)
    ->where('expires_at', '>', Date::now())
    ->get()
    ->filter(fn (Token $token) => $token->client->hasGrantType('personal_access'));

ルート保護Protecting Routes

ミドルウェアによる保護Via Middleware

Passportは、受信リクエストのアクセストークンを検証する認証グラントを用意しています。passportドライバを使用するようにapiガードを設定したら、有効なアクセストークンを必要とするルートでauth:apiミドルウェアを指定するだけで済みます。Passport includes an authentication guard[/docs/{{version}}/authentication#adding-custom-guards] that will validate access tokens on incoming requests. Once you have configured the api guard to use the passport driver, you only need to specify the auth:api middleware on any routes that should require a valid access token:

Route::get('/user', function () {
    // API認証ユーザーのみがこのルートにアクセス可能
})->middleware('auth:api');

warning Warning! クライアント認証グラントを使用している場合、auth:apiミドルウェアの代わりに、ルートを保護するためにLaravel\Passport\Http\Middleware\EnsureClientIsResourceOwnerミドルウェアを使うべきです。[!WARNING] If you are using the client credentials grant[#client-credentials-grant], you should use the Laravel\Passport\Http\Middleware\EnsureClientIsResourceOwner middleware[#client-credentials-grant] to protect your routes instead of the auth:api middleware.

複数認証ガードMultiple Authentication Guards

アプリケーションの認証でたぶんまったく異なるEloquentモデルを使用する、別々のタイプのユーザーを認証する場合、それぞれのユーザープロバイダタイプごとにガード設定を定義する必用があるでしょう。これにより特定ユーザープロバイダ向けのリクエストを保護できます。例としてconfig/auth.php設定ファイルで以下のようなガード設定を行っているとしましょう。If your application authenticates different types of users that perhaps use entirely different Eloquent models, you will likely need to define a guard configuration for each user provider type in your application. This allows you to protect requests intended for specific user providers. For example, given the following guard configuration the config/auth.php configuration file:

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

    'api-customers' => [
        'driver' => 'passport',
        'provider' => 'customers',
    ],
],

以下のルートは受信リクエストを認証するためcustomersユーザープロバイダを使用するapi-customersガードを使用します。The following route will utilize the api-customers guard, which uses the customers user provider, to authenticate incoming requests:

Route::get('/customer', function () {
    // ...
})->middleware('auth:api-customers');

note Note: Passportで複数のユーザープロバイダを使用する際の詳細は、パーソナルアクセストークンのドキュメントおよびパスワードグラントのドキュメントを参照してください。[!NOTE] For more information on using multiple user providers with Passport, please consult the personal access tokens documentation[#customizing-the-user-provider-for-pat] and password grant documentation[#customizing-the-user-provider].

アクセストークンの受け渡しPassing the Access Token

Passportで保護しているルートを呼び出す場合、アプリケーションのAPI使用側はリクエストのAuthorizationヘッダに、Bearerトークンとしてアクセストークンを指定する必要があります。例として、Httpファサードを使用する場合を御覧ください。When calling routes that are protected by Passport, your application's API consumers should specify their access token as a Bearer token in the Authorization header of their request. For example, when using the Http Facade:

use Illuminate\Support\Facades\Http;

$response = Http::withHeaders([
    'Accept' => 'application/json',
    'Authorization' => "Bearer $accessToken",
])->get('https://passport-app.test/api/user');

return $response->json();

トークンのスコープToken Scopes

スコープは、あるアカウントにアクセスする許可がリクエストされたとき、あなたのAPIクライアントに限定された一連の許可をリクエストできるようにします。たとえば、eコマースアプリケーションを構築している場合、全API利用者へ発注する許可を与える必要はないでしょう。代わりに、利用者へ注文の発送状況にアクセスできる許可を与えれば十分です。言い換えれば、スコープはアプリケーションユーザーに対し、彼らの代理としてのサードパーティアプリケーションが実行できるアクションを制限できるようにします。Scopes allow your API clients to request a specific set of permissions when requesting authorization to access an account. For example, if you are building an e-commerce application, not all API consumers will need the ability to place orders. Instead, you may allow the consumers to only request authorization to access order shipment statuses. In other words, scopes allow your application's users to limit the actions a third-party application can perform on their behalf.

スコープの定義Defining Scopes

APIのスコープは、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドで、Passport::tokensCanメソッドを使用して定義してください。tokensCanメソッドは、スコープ名とスコープの説明の配列を引数に取ります。スコープの説明は何でもよく、認可の承認画面でユーザーへ表示します。You may define your API's scopes using the Passport::tokensCan method in the boot method of your application's App\Providers\AppServiceProvider class. The tokensCan method accepts an array of scope names and scope descriptions. The scope description may be anything you wish and will be displayed to users on the authorization approval screen:

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    Passport::tokensCan([
        'user:read' => 'Retrieve the user info',
        'orders:create' => 'Place orders',
        'orders:read:status' => 'Check order status',
    ]);
}

デフォルトスコープDefault Scope

クライアントが特定のスコープを要求しない場合に、defaultScopesメソッドを使用して、トークンにデフォルトのスコープを付与するようにPassportサーバを設定できます。通常、このメソッドはアプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドから呼び出します。If a client does not request any specific scopes, you may configure your Passport server to attach default scopes to the token using the defaultScopes method. Typically, you should call this method from the boot method of your application's App\Providers\AppServiceProvider class:

use Laravel\Passport\Passport;

Passport::tokensCan([
        'user:read' => 'Retrieve the user info',
        'orders:create' => 'Place orders',
        'orders:read:status' => 'Check order status',
]);

Passport::defaultScopes([
    'user:read',
    'orders:create',
]);

トークンへのスコープ割り付けAssigning Scopes to Tokens

許可コードのリクエスト時When Requesting Authorization Codes

許可コードグラントを用い、アクセストークンをリクエストする際、利用者はscopeクエリ文字列パラメータとして、希望するスコープを指定する必要があります。scopeパラメータはスコープを空白で区切ったリストです。When requesting an access token using the authorization code grant, consumers should specify their desired scopes as the scope query string parameter. The scope parameter should be a space-delimited list of scopes:

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'your-client-id',
        'redirect_uri' => 'https://third-party-app.com/callback',
        'response_type' => 'code',
        'scope' => 'user:read orders:create',
    ]);

    return redirect('https://passport-app.test/oauth/authorize?'.$query);
});

パーソナルアクセストークン発行時When Issuing Personal Access Tokens

App\Models\UserモデルのcreateTokenメソッドを使用してパーソナルアクセストークンを発行している場合は、メソッドの2番目の引数に目的のスコープの配列を渡すことができます。If you are issuing personal access tokens using the App\Models\User model's createToken method, you may pass the array of desired scopes as the second argument to the method:

$token = $user->createToken('My Token', ['orders:create'])->accessToken;

スコープのチェックChecking Scopes

Passportは受信リクエストが、与えるトークンの指定したスコープで認証されていることを検証するために使用できる2つのミドルウェアを持っています。Passport includes two middleware that may be used to verify that an incoming request is authenticated with a token that has been granted a given scope.

全スコープの確認Check For All Scopes

受信リクエストのアクセストークンが、リストしたすべてのスコープを持つことを検証するには、Laravel\Passport\Http\Middleware\CheckTokenミドルウェアをルートへ指定してください。The Laravel\Passport\Http\Middleware\CheckToken middleware may be assigned to a route to verify that the incoming request's access token has all the listed scopes:

use Laravel\Passport\Http\Middleware\CheckToken;

Route::get('/orders', function () {
    // アクセストークンは"orders:read"と"orders:create"両方のスコープを持つ
})->middleware(['auth:api', CheckToken::using('orders:read', 'orders:create');

一部のスコープの確認Check for Any Scopes

受信リクエストのアクセストークンが、リストしたスコープのうち少なくとも1つを持つことを検証するには、Laravel\Passport\Http\Middleware\CheckTokenForAnyScopeミドルウェアをルートに割り当ててください。The Laravel\Passport\Http\Middleware\CheckTokenForAnyScope middleware may be assigned to a route to verify that the incoming request's access token has at least one of the listed scopes:

use Laravel\Passport\Http\Middleware\CheckTokenForAnyScope;

Route::get('/orders', function () {
    // アクセストークンは"orders:read"か"orders:create"スコープのどれかを持つ
})->middleware(['auth:api', CheckTokenForAnyScope::using('orders:read', 'orders:create');

トークンインスタンスでのスコープチェックChecking Scopes on a Token Instance

アクセストークンの認証済みリクエストがアプリケーションに入力された後でも、認証済みのApp\Models\UserインスタンスでtokenCanメソッドを使用して、トークンに特定のスコープがあるかどうかを確認できます。Once an access token authenticated request has entered your application, you may still check if the token has a given scope using the tokenCan method on the authenticated App\Models\User instance:

use Illuminate\Http\Request;

Route::get('/orders', function (Request $request) {
    if ($request->user()->tokenCan('orders:create')) {
        // ...
    }
});

その他のスコープメソッドAdditional Scope Methods

scopeIdsメソッドは定義済みの全ID/名前の配列を返します。The scopeIds method will return an array of all defined IDs / names:

use Laravel\Passport\Passport;

Passport::scopeIds();

scopesメソッドは定義済みの全スコープをLaravel\Passport\Scopeのインスタンスの配列として返します。The scopes method will return an array of all defined scopes as instances of Laravel\Passport\Scope:

Passport::scopes();

scopesForメソッドは、指定したID/名前に一致するLaravel\Passport\Scopeインスタンスの配列を返します。The scopesFor method will return an array of Laravel\Passport\Scope instances matching the given IDs / names:

Passport::scopesFor(['user:read', 'orders:create']);

指定したスコープが定義済みであるかを判定するには、hasScopeメソッドを使います。You may determine if a given scope has been defined using the hasScope method:

Passport::hasScope('orders:create');

SPA認証SPA Authentication

API構築時にJavaScriptアプリケーションから、自分のAPIを利用できたらとても便利です。このAPI開発のアプローチにより、世界中で共有されるのと同一のAPIを自身のアプリケーションで使用できるようになります。自分のWebアプリケーションやモバイルアプリケーション、サードパーティアプリケーション、そしてさまざまなパッケージマネージャ上で公開するSDKにより、同じAPIが使用されます。When building an API, it can be extremely useful to be able to consume your own API from your JavaScript application. This approach to API development allows your own application to consume the same API that you are sharing with the world. The same API may be consumed by your web application, mobile applications, third-party applications, and any SDKs that you may publish on various package managers.

通常、JavaScriptアプリケーションからAPIを利用する場合、手作業でアクセストークンをアプリケーションへ送信し、アプリケーションへリクエストするたび、アクセストークンを渡す必要があります。しかし、Passportは、この処理を代行するミドルウェアを用意しています。アプリケーションのbootstrap/app.phpファイルのwebミドルウェアグループにCreateFreshApiTokenミドルウェアを追加するだけです。Typically, if you want to consume your API from your JavaScript application, you would need to manually send an access token to the application and pass it with each request to your application. However, Passport includes a middleware that can handle this for you. All you need to do is append the CreateFreshApiToken middleware to the web middleware group in your application's bootstrap/app.php file:

use Laravel\Passport\Http\Middleware\CreateFreshApiToken;

->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        CreateFreshApiToken::class,
    ]);
})

warning Warning! ミドルウェアの指定の中で、CreateFreshApiTokenミドルウェアは確実に最後へリストしてください。[!WARNING] You should ensure that the CreateFreshApiToken middleware is the last middleware listed in your middleware stack.

このミドルウェアは、送信レスポンスにlaravel_tokenクッキーを添付します。このクッキーには、PassportがJavaScriptアプリケーションからのAPIリクエストを認証するために使用する暗号化されたJWTが含まれています。JWTの有効期間は、session.lifetime設定値と同じです。これで、ブラウザは後続のすべてのリクエストでクッキーを自動的に送信するため、アクセストークンを明示的に渡さなくても、アプリケーションのAPIにリクエストを送信できます。This middleware will attach a laravel_token cookie to your outgoing responses. This cookie contains an encrypted JWT that Passport will use to authenticate API requests from your JavaScript application. The JWT has a lifetime equal to your session.lifetime configuration value. Now, since the browser will automatically send the cookie with all subsequent requests, you may make requests to your application's API without explicitly passing an access token:

axios.get('/api/user')
    .then(response => {
        console.log(response.data);
    });

クッキー名のカスタマイズCustomizing the Cookie Name

必要であれば、Passport::cookieメソッドをつかい、laravel_tokenクッキーの名前をカスタマイズできます。通常、このメソッドはアプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドから呼び出します。If needed, you can customize the laravel_token cookie's name using the Passport::cookie method. Typically, this method should be called from the boot method of your application's App\Providers\AppServiceProvider class:

/**
 * 全アプリケーションサービスの初期起動処理
 */
public function boot(): void
{
    Passport::cookie('custom_name');
}

CSRF保護CSRF Protection

この認証方法を使用する場合、リクエストに有効なCSRFトークンヘッダを確実に含める必要があります。スケルトンアプリケーションとすべてのスターターキットに含まれるデフォルトのLaravel JavaScriptスカフォールドにはAxiosインスタンスを含んでおり、暗号化したXSRF-TOKENクッキーの値を自動的に使用して、同一オリジンのリクエストへX-XSRF-TOKENヘッダを送信します。When using this method of authentication, you will need to ensure a valid CSRF token header is included in your requests. The default Laravel JavaScript scaffolding included with the skeleton application and all starter kits includes an Axios[https://github.com/axios/axios] instance, which will automatically use the encrypted XSRF-TOKEN cookie value to send an X-XSRF-TOKEN header on same-origin requests.

note Note: X-XSRF-TOKENの代わりにX-CSRF-TOKENヘッダを送る方法を取る場合は、csrf_token()により提供される復元したトークンを使用する必要があります。[!NOTE] If you choose to send the X-CSRF-TOKEN header instead of X-XSRF-TOKEN, you will need to use the unencrypted token provided by csrf_token().

イベントEvents

Passportはアクセストークンやリフレッシュトークンを発行する際に、イベントを発生させます。これらのイベントをリッスンして、データベース内の他のアクセストークンを削除したり取り消したりできます。Passport raises events when issuing access tokens and refresh tokens. You may listen for these events[/docs/{{version}}/events] to prune or revoke other access tokens in your database:

イベント名Event Name
Laravel\Passport\Events\AccessTokenCreatedLaravel\Passport\Events\AccessTokenCreated
Laravel\Passport\Events\RefreshTokenCreatedLaravel\Passport\Events\RefreshTokenCreated

テストTesting

PassportのactingAsメソッドは、現在認証中のユーザーを指定すると同時にスコープも指定します。actingAsメソッドの最初の引数はユーザーのインスタンスで、第2引数はユーザートークンに許可するスコープ配列を指定します。Passport's actingAs method may be used to specify the currently authenticated user as well as its scopes. The first argument given to the actingAs method is the user instance and the second is an array of scopes that should be granted to the user's token:

Pest
use App\Models\User;
use Laravel\Passport\Passport;

test('orders can be created', function () {
    Passport::actingAs(
        User::factory()->create(),
        ['orders:create']
    );

    $response = $this->post('/api/orders');

    $response->assertStatus(201);
});
PHPUnit
use App\Models\User;
use Laravel\Passport\Passport;

public function test_orders_can_be_created(): void
{
    Passport::actingAs(
        User::factory()->create(),
        ['orders:create']
    );

    $response = $this->post('/api/orders');

    $response->assertStatus(201);
}

PassportのactingAsClientメソッドは、現在認証中のクライアントを指定すると同時にスコープも指定します。actingAsClientメソッドの最初の引数はクライアントインスタンスで、第2引数はクライアントのトークンへ許可するスコープの配列です。Passport's actingAsClient method may be used to specify the currently authenticated client as well as its scopes. The first argument given to the actingAsClient method is the client instance and the second is an array of scopes that should be granted to the client's token:

Pest
use Laravel\Passport\Client;
use Laravel\Passport\Passport;

test('servers can be retrieved', function () {
    Passport::actingAsClient(
        Client::factory()->create(),
        ['servers:read']
    );

    $response = $this->get('/api/servers');

    $response->assertStatus(200);
});
PHPUnit
use Laravel\Passport\Client;
use Laravel\Passport\Passport;

public function test_servers_can_be_retrieved(): void
{
    Passport::actingAsClient(
        Client::factory()->create(),
        ['servers:read']
    );

    $response = $this->get('/api/servers');

    $response->assertStatus(200);
}

章選択

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
JSフレームワーク
両フレームワーク
Reactのみ表示
Vueのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作