Laravel 6.0 API認証

イントロダクション

アプリケーションの各ユーザーに結びつけたランダムトークンを利用し、API認証を行うシンプルな手法をデフォルトとしてLaravelは採用しています。config/auth.php設定ファイルの中で、apiガードはtokenドライバを定義し、使用しています。このドライバーは、受信したリクエストのAPIトークンを調べ、データベース上のユーザーに結びつけたトークンと一致するか検証することに責任を持っています。

Note: Laravelでは、シンプルなトークンベースの認証ガードを提供していますが、API認証を提供する堅牢なプロダクションアプリケーションでは、Laravel Passportの使用を考慮することを強くおすすめします。

設定

データベースの準備

tokenドライバを使用する前に、usersテーブルへapi_tokenカラムを追加するマイグレーションを作成する必要があります。

Schema::table('users', function ($table) {
    $table->string('api_token', 80)->after('password')
                        ->unique()
                        ->nullable()
                        ->default(null);
});

マイグレーションが出来上がったら、migrate Artisanコマンドを実行します。

Tip!! 他のカラム名を使う場合は、config/auth.php設定ファイル中のstorage_key設定オプションを必ず更新してください。

トークン生成

usersテーブルへapi_tokenカラムを追加したら、アプリケーションに登録している各ユーザーへ、ランダムなAPIトークンを割り付ける準備が整いました。ユーザーの登録でUserモデル生成時に、トークンを割り付けるべきでしょう。laravel/ui Composerパッケージが提供する認証スカフォールドを使用する場合は、RegisterControllercreateメソッドで行っています。

use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

/**
 * 登録バリデーション後に、新ユーザーインスタンスの生成
 *
 * @param  array  $data
 * @return \App\User
 */
protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
        'api_token' => Str::random(60),
    ]);
}

トークンのハッシュ

前記の例では、APIトークンはデータベースへ平文のまま保存されます。SHA-256を使用し、APIトークンをハッシュしたい場合は、apiガードのhashオプションをtrueに設定してください。apiガードはconfig/auth.php設定ファイルで定義されています。

'api' => [
    'driver' => 'token',
    'provider' => 'users',
    'hash' => true,
],

ハッシュ済みトークンの生成

ハッシュ済みAPIトークンを使用する場合、ユーザー登録時にAPIトークンを生成してはいけません。代わりに、アプリケーション中にAPIトークン管理ページを実装する必要があります。このページでユーザーにAPIトークンの初期化と再生成を提供します。あるユーザーがトークンの初期化や再生成をリクエストしたら、トークンのハッシュ済みコピーをデータベースへ保存し、ビューやフロントエンドクライアントで一度だけ表示するために、平文のコピーを返す必要があります。

たとえば、指定したユーザーのトークンを初期化/再生成し、JSONレスポンスとして平文トークンを返すコントローラメソッドは、次のようになるでしょう。

<?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(60);

        $request->user()->forceFill([
            'api_token' => hash('sha256', $token),
        ])->save();

        return ['token' => $token];
    }
}

Tip!! 上記例のAPIトークンは、十分なエントロピーを持ちますので、「レインボーテーブル」を作成してハッシュ済みトークンのオリジナル値を探し出すのは、非現実的になります。そのため、bcryptなどの遅いハッシュ方法は不必要ありません。

ルートの保護

Laravelは、受信したリクエストのAPIトークンを自動的にバリデートする、認証ガードを提供しています。アクセストークンの有効性が必要なルートへ、auth:apiミドルウェアを指定するだけです。

use Illuminate\Http\Request;

Route::middleware('auth:api')->get('/user', function(Request $request) {
    return $request->user();
});

リクエストへのトークン付加

アプリケーションへAPIトークンを渡す方法はいくつかあります。Guzzle HTTPライブラリを使用したときの利用方法をデモンストレーションするために、いくつかのアプローチを検討してみます。アプリケーションの必要に合わせて選択してください。

クエリ文字列

アプリケーションのAPI利用側が、api_tokenクエリ文字列の値としてトークンを指定できます。

$response = $client->request('GET', '/api/user?api_token='.$token);

ペイロードのリクエスト

アプリケーションのAPI利用側が、リクエストフォームのapi_tokenパラメータへ、APIトークンを含められます。

$response = $client->request('POST', '/api/user', [
    'headers' => [
        'Accept' => 'application/json',
    ],
    'form_params' => [
        'api_token' => $token,
    ],
]);

Bearerトークン

アプリケーションのAPI利用側が、リクエストのAuthorizationヘッダへBearerトークンとして、APIトークンを提供できます。

$response = $client->request('POST', '/api/user', [
    'headers' => [
        'Authorization' => 'Bearer '.$token,
        'Accept' => 'application/json',
    ],
]);

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる