LaravelにはAPIトークンを用いてユーザを認証する仕組みが組み込まれています。拡張機能であるLaravel Passportというものもありますが、この記事では組み込みのAPI認証についてのみ述べます。
API認証 6.x Laravel
LaravelのAPI認証の説明はあっさりしています。認証対象のユーザやら管理者やらのテーブルにapi_tokenカラムを用意し、ミドルウェアで囲って認証範囲のルーティングを指定し、リクエストでのapi_tokenの渡し方を紹介して終わりです。実装を読んでみるとドキュメントにありませんが、外部から設定されるべき値がいくつか見つかります。
最たるものはconfigです。通常Laravelの認証設定はconfig/auth.phpに次の様に書くだけです。
/* |-------------------------------------------------------------------------- | 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’)の場合はさらに設定を追加できます。
'guards' => [ 'api' => [ 'driver' => 'token', 'provider' => 'users', 'input_key' => 'authToken', // リクエストのキー指定 'storage_key' => 'auth_token', // カラム名指定 'hash' => true, // トークンをハッシュ化して保存するか否か.これはドキュメントにある ], ],
これは\Illuminate\Auth\AuthManager::createTokenDriverにあります。次の様に設定があるならばそれを、なければapi_token等デフォルト値を選ぶようになっています。
/** * 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にトークンを渡すことでも認証を動かせることが分かります。
// 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'); }