イントロダクションIntroduction
アプリケーションの各ユーザーに結びつけたランダムトークンを利用し、API認証を行うシンプルな手法をデフォルトとしてLaravelは採用しています。config/auth.php設定ファイルの中で、apiガードはtokenドライバを定義し、使用しています。このドライバーは、受信したリクエストのAPIトークンを調べ、データベース上のユーザーに結びつけたトークンと一致するか検証することに責任を持っています。By default, Laravel ships with a simple solution to API authentication via a random token assigned to each user of your application. In your config/auth.php configuration file, an api guard is already defined and utilizes a token driver. This driver is responsible for inspecting the API token on the incoming request and verifying that it matches the user's assigned token in the database.
Note: Laravelでは、シンプルなトークンベースの認証ガードを提供していますが、API認証を提供する堅牢なプロダクションアプリケーションでは、Laravel Passportの使用を考慮することを強く推奨します。Note: While Laravel ships with a simple, token based authentication guard, we strongly recommend you consider using Laravel Passport[/docs/{{version}}/passport] for robust, production applications that offer API authentication.
設定Configuration
データベースの準備Database Preparation
tokenドライバを使用する前に、usersテーブルへapi_tokenカラムを追加するマイグレーションを作成する必要があります。Before using the token driver, you will need to create a migration[/docs/{{version}}/migrations] which adds an api_token column to your users table:
Schema::table('users', function ($table) {
$table->string('api_token', 80)->after('password')
->unique()
->nullable()
->default(null);
});
マイグレーションできたら、migrate Artisanコマンドを実行します。Once the migration has been created, run the migrate Artisan command.
">Tip!! 他のカラム名を使う場合は、
config/auth.php設定ファイル中のstorage_key設定オプションを必ず更新してください。{tip} If you choose to use a different column name, be sure to update your API'sstorage_keyconfiguration option within theconfig/auth.phpconfiguration file.
トークン生成Generating Tokens
usersテーブルへapi_tokenカラムを追加したら、アプリケーションに登録している各ユーザーへ、ランダムなAPIトークンを割り付ける準備が整いました。ユーザーの登録でUserモデル生成時に、トークンを割り付けるべきでしょう。laravel/ui Composerパッケージが提供する認証スカフォールドを使用する場合は、RegisterControllerのcreateメソッドで行っています。Once the api_token column has been added to your users table, you are ready to assign random API tokens to each user that registers with your application. You should assign these tokens when a User model is created for the user during registration. When using the authentication scaffolding[/docs/{{version}}/authentication#authentication-quickstart] provided by the laravel/ui Composer package, this may be done in the create method of the RegisterController:
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
/**
* 登録バリデーション後に、新ユーザーインスタンスの生成
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::forceCreate([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'api_token' => Str::random(80),
]);
}
トークンのハッシュHashing Tokens
前記の例では、APIトークンはデータベースへ平文のまま保存されます。SHA-256を使用し、APIトークンをハッシュしたい場合は、apiガードのhashオプションをtrueに設定してください。apiガードはconfig/auth.php設定ファイルで定義されています。In the examples above, API tokens are stored in your database as plain-text. If you would like to hash your API tokens using SHA-256 hashing, you may set the hash option of your api guard configuration to true. The api guard is defined in your config/auth.php configuration file:
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => true,
],
ハッシュ済みトークンの生成Generating Hashed Tokens
ハッシュ済みAPIトークンを使用する場合、ユーザー登録時にAPIトークンを生成してはいけません。代わりに、アプリケーション中にAPIトークン管理ページを実装する必要があります。このページでユーザーにAPIトークンの初期化と再生成を提供します。あるユーザーがトークンの初期化や再生成をリクエストしたら、トークンのハッシュ済みコピーをデータベースへ保存し、ビューやフロントエンドクライアントで一度だけ表示するために、平文のコピーを返す必要があります。When using hashed API tokens, you should not generate your API tokens during user registration. Instead, you will need to implement your own API token management page within your application. This page should allow users to initialize and refresh their API token. When a user makes a request to initialize or refresh their token, you should store a hashed copy of the token in the database, and return the plain-text copy of token to the view / frontend client for one-time display.
たとえば、指定したユーザーのトークンを初期化/再生成し、JSONレスポンスとして平文トークンを返すコントローラメソッドは、次のようになるでしょう。For example, a controller method that initializes / refreshes the token for a given user and returns the plain-text token as a JSON response might look like the following:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class ApiTokenController extends Controller
{
/**
* 認証済みのユーザーのAPIトークンを更新する
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function update(Request $request)
{
$token = Str::random(80);
$request->user()->forceFill([
'api_token' => hash('sha256', $token),
])->save();
return ['token' => $token];
}
}
">Tip!! 上記例のAPIトークンは、十分なエントロピーを持ちますので、「レインボーテーブル」を作成してハッシュ済みトークンのオリジナル値を探し出すのは、非現実的になります。そのため、
bcryptなどの遅いハッシュ方法は必要ありません。{tip} Since the API tokens in the example above have sufficient entropy, it is impractical to create "rainbow tables" to lookup the original value of the hashed token. Therefore, slow hashing methods such asbcryptare unnecessary.
ルートの保護Protecting Routes
Laravelは、受信したリクエストのAPIトークンを自動的にバリデートする、認証ガードを提供しています。アクセストークンの有効性が必要なルートへ、auth:apiミドルウェアを指定するだけです。Laravel includes an authentication guard[/docs/{{version}}/authentication#adding-custom-guards] that will automatically validate API tokens on incoming requests. You only need to specify the auth:api middleware on any route that requires a valid access token:
use Illuminate\Http\Request;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
リクエストへのトークン付加Passing Tokens In Requests
アプリケーションへAPIトークンを渡す方法はいくつかあります。Guzzle HTTPライブラリを使用したときの利用方法をデモンストレーションするために、いくつかのアプローチを検討してみます。アプリケーションの必要に合わせて選択してください。There are several ways of passing the API token to your application. We'll discuss each of these approaches while using the Guzzle HTTP library to demonstrate their usage. You may choose any of these approaches based on the needs of your application.
クエリ文字列Query String
アプリケーションのAPI利用側が、api_tokenクエリ文字列の値としてトークンを指定できます。Your application's API consumers may specify their token as an api_token query string value:
$response = $client->request('GET', '/api/user?api_token='.$token);
ペイロードのリクエストRequest Payload
アプリケーションのAPI利用側が、リクエストフォームのapi_tokenパラメータへ、APIトークンを含められます。Your application's API consumers may include their API token in the request's form parameters as an api_token:
$response = $client->request('POST', '/api/user', [
'headers' => [
'Accept' => 'application/json',
],
'form_params' => [
'api_token' => $token,
],
]);
BearerトークンBearer Token
アプリケーションのAPI利用側が、リクエストのAuthorizationヘッダへBearerトークンとして、APIトークンを提供できます。Your application's API consumers may provide their API token as a Bearer token in the Authorization header of the request:
$response = $client->request('POST', '/api/user', [
'headers' => [
'Authorization' => 'Bearer '.$token,
'Accept' => 'application/json',
],
]);