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');
}