イントロダクション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_key
configuration option within theconfig/auth.php
configuration 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 asbcrypt
are 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',
],
]);