LaravelにはAPIトークンを用いてユーザを認証する仕組みが組み込まれています。拡張機能であるLaravel Passportというものもありますが、この記事では組み込みのAPI認証についてのみ述べます。
API認証 6.x Laravel
LaravelのAPI認証の説明はあっさりしています。認証対象のユーザやら管理者やらのテーブルにapi_tokenカラムを用意し、ミドルウェアで囲って認証範囲のルーティングを指定し、リクエストでのapi_tokenの渡し方を紹介して終わりです。実装を読んでみるとドキュメントにありませんが、外部から設定されるべき値がいくつか見つかります。
最たるものはconfigです。通常Laravelの認証設定はconfig/auth.phpに次の様に書くだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | 次に、アプリケーションのすべての認証ガードを定義できます。 | もちろん、ここではセッションストレージとEloquentユーザープロバイダーを使用する優れたデフォルト構成が定義されています。 | | すべての認証ドライバーにはユーザープロバイダーがあります。 | これは、ユーザーのデータを保持するためにこのアプリケーションで使用されるデータベース | または他のストレージメカニズムからユーザーを実際に取得する方法を定義します。 | | Supported: "session", "token" | */ 'guards' => [ 'web' => [ 'driver' => 'session' , 'provider' => 'users' , ], 'api' => [ 'driver' => 'token' , 'provider' => 'users' , ], ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | すべての認証ドライバーにはユーザープロバイダーがあります。 | これは、ユーザーのデータを保持するためにこのアプリケーションで使用されるデータベース | または他のストレージメカニズムからユーザーを実際に取得する方法を定義します。 | | 複数のユーザーテーブルまたはモデルがある場合は、複数を構成できます | 各モデル/テーブルを表すソース。 これらのソースはその後 | 定義した追加の認証ガードに割り当てられます。 | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent' , 'model' => App\Models\Eloquents\User:: class , ], ], |
APIトークンによる認証(gurads.driver === ‘token’)の場合はさらに設定を追加できます。
1 2 3 4 5 6 7 8 9 | 'guards' => [ 'api' => [ 'driver' => 'token' , 'provider' => 'users' , 'input_key' => 'authToken' , // リクエストのキー指定 'storage_key' => 'auth_token' , // カラム名指定 'hash' => true, // トークンをハッシュ化して保存するか否か.これはドキュメントにある ], ], |
これは\Illuminate\Auth\AuthManager::createTokenDriverにあります。次の様に設定があるならばそれを、なければapi_token等デフォルト値を選ぶようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /** * Create a token based authentication guard. * * @param string $name * @param array $config * @return \Illuminate\Auth\TokenGuard */ public function createTokenDriver( $name , $config ) { // The token guard implements a basic API token based guard implementation // that takes an API token field from the request and matches it to the // user in the database or another persistence layer where users are. $guard = new TokenGuard( $this ->createUserProvider( $config [ 'provider' ] ?? null), $this ->app[ 'request' ], $config [ 'input_key' ] ?? 'api_token' , $config [ 'storage_key' ] ?? 'api_token' , $config [ 'hash' ] ?? false ); $this ->app->refresh( 'request' , $guard , 'setRequest' ); return $guard ; } |
また、ここからトークン認証定義クラスTokenGuardを追って\Illuminate\Auth\TokenGuard::getTokenForRequestまで行くとドキュメントにないキーであるリクエストヘッダのPHP_AUTH_PWにトークンを渡すことでも認証を動かせることが分かります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // vendor/laravel/framework/src/Illuminate/Auth/TokenGuard.php /** * Get the token for the current request. * * @return string */ public function getTokenForRequest() { $token = $this ->request->query( $this ->inputKey); if ( empty ( $token )) { $token = $this ->request->input( $this ->inputKey); } if ( empty ( $token )) { $token = $this ->request->bearerToken(); } if ( empty ( $token )) { // これがドキュメントにないやり方 $token = $this ->request->getPassword(); } return $token ; } // vendor/symfony/http-foundation/Request.php /** * Returns the password. * * @return string|null */ public function getPassword() { return $this ->headers->get( 'PHP_AUTH_PW' ); } |