これを読めばLaravel Airlockがわかる(Token編)
Laravel7で新たに認証に関する機能を持つLaravel Airlockが追加されました。Laravel Airlockは2つの機能を持ち、1つはこれまで馴染みのあるAPI Tokenを利用したAPI Token認証、もうひとつはCookieを利用しSPAでの利用を想定したSPA認証です。本文書では1つ目のAPI Tokenを用いた認証の使用方法を確認します。
Laravel AirlockからLaravel Sanctumと名称が変更になりました。内容を更新してLaravel Sanctumとして新たに記事を公開しています。
目次
Laravel Airlock
Laravel AirlockのAPI Tokenを利用する方法は非常にシンプルでTokenを作成し、その作成したTokenをリクエストと一緒に送信して認証を行うことでアクセスの可否が決まります。
Laravelのインストール
Laravel Airlockの動作確認を行うためには事前にLaravel7のインストールを行なっておく必要があります。Laravel7のインストールについては下記を参考にしてください。
Laravel Airlockパッケージのインストール
Laravel Airlockを利用するためにはlaravel/airlockパッケージのインストールを行う必要があります。
$ composer require laravel/airlock
設定ファイルとテーブルの作成
laravel airlockの設定ファイル(airlock.php)とpersonal_access_tokensテーブルのマイグレーションファイルの作成を行います。personal_access_tokesテーブルにToken情報を保存します。
$ php artisan vendor:publish --provider="Laravel\Airlock\AirlockServiceProvider"
Copied Directory [/vendor/laravel/airlock/database/migrations] To [/database/migrations]
Copied File [/vendor/laravel/airlock/config/airlock.php] To [/config/airlock.php]
Publishing complete.
マイグレーションファイルがdatabase¥migrationsの下に作成されているのでphp artisan migrateコマンドを実行します。
$ php artisan migrate
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated: 2019_12_14_000001_create_personal_access_tokens_table (0.01 seconds)
API Tokenの設定
UserモデルにtraitのHasApiTokesを追加します。HasApiTokesトレイトにはトークンの作成を行うcreateTokenメソッドなどが含まれている
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Airlock\HasApiTokens; //追加
class User extends Authenticatable
{
use Notifiable, HasApiTokens; //追加
//省略
Tokenの作成
API Tokenの作成はHasApiTokesトレイトに含まれているので以下のメソッドで新しいトークンを作成することができます。
$token = $user->createToken('token-name');
return $token->plainTextToken; //これがトークン
$token->plainTextTokenでトークンを取得することができます。token-nameには任意の名前をつけることが可能です。
TokenはLaravelの外側のアプリケーションからLaravelに対してPOSTリクエストでemailとpasswordを送信し認証が完了した後に作成を行います。
api.phpにトークン作成用のルーティング/airlock/tokenを追加します。
トークン作成の下記のコードについてはLaravelのマニュアルを参考に作成しています。
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
/*
中略
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('/airlock/token', function (Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required'
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
return $user->createToken($request->device_name)->plainTextToken;
});
内容はPOSTリクエストを受け取ったら、emailとpasswordとdevice_nameでバリデーションを実行します。バリデーションに失敗したらエラーが戻されます。バリデーションを通過後ユーザ情報をデータベースから取得し、そのユーザが存在した場合にTokenの作成を行います。作成したTokenはPOSTリクエストを送信してきたアプリケーションに戻されます。
アプリケーションにRest Clientを利用
外側からアプリケーションのアクセスの動作確認を行うためVisual Code StudioのREST Clientを利用します。
REST Clientを利用するためにはまずXXXX.httpファイルを作成してください。XXXXは任意の名前で拡張子はhttpです。ここではtest.httpというファイルを作成します。
test.httpファイルでLaravelの/api/airlock/tokenに対してPOSTリクエストを送信します。
動作確認のため存在しないユーザのemailアドレスを入れてください。
POST http://127.0.0.1:8000/api/airlock/token/
Content-Type: application/json
Accept: application/json
{
"email": "johndoe@test.com",
"password": "password",
"device_name": "test"
}
上記をtest.httpファイルに記述したらPOSTの上に表示されるSend Requestをクリックしてください。POSTリクエストが送信され、emailが存在しないので”The Provided credentials are incorrect.”エラーが戻されます。
次は正しいemailアドレスとpasswordを入れてPOSTリクエストを送信してください。エラーではなく下記のような文字列が戻されるはずです。これがTokenです。
Bj7IiCNUXr0D0Cebi8B4PtJsHio7fSOxkRBBBD4IqLFay5p04hcx15NIoehjYu4i1jMYY5w1QQkzzEQJ
このTokenは次のリクエストに利用するため保存しておく必要があります。
何度もリクエストを行うとPOSTリクエストが成功した回数だけTokenが新規で作成されます。上書きされるわけではありません。
作成されたTokenの確認
TokenがPOSTリクエストから戻されたのでTokenがpersonal_access_tokensテーブルに存在するか確認してみましょう。
sqliteデータベースを利用しているコマンドラインで接続してテーブルの中身を確認してみましょう。
$ cd database
$ sqlite3 database.sqlite
sqlite> .headers on
sqlite> select * from personal_access_tokens;
id|tokenable_type|tokenable_id|name|token|abilities|last_used_at|created_at|updated_at
1|App\User|1|test|300e7aae2278a7f4e20415c8d6755d1a3cec6df734710d315fb490592cde3fd3|["*"]||2020-03-06 05:09:06|2020-03-06 05:09:06
Hashされているので取得したTokenとテーブルの中のTokenの文字列は異なります。
Tokenを利用したアクセス
Tokenを取得することができたので取得したTokenを利用してアクセス制限のあるLaravelのリソースにアクセスを行います。
api.phpファイルにデフォルトで存在する下記のURLにアクセスします。
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
middlewareにapiが使われていますがairlockを利用する場合はauth:airlockに変更する必要があります。
Route::middleware('auth:airlock')->get('/user', function (Request $request) {
return $request->user();
});
REST Clientを使うのでtest.httpファイルにGETリクエストを追加します。取得したTokenはAuthorization: Bearer Tokenで設定を行います。
GET http://127.0.0.1:8000/api/user/
Content-Type: application/json
Accept: application/json
Authorization: Bearer Bj7IiCNUXr0D0Cebi8B4PtJsHio7fSOxkRBBBD4IqLFay5p04hcx15NIoehjYu4i1jMYY5w1QQkzzEQJ
Send Requestをクリックしてユーザ情報が取得できればToken認証は成功しています。
HTTP/1.1 200 OK
Host: 127.0.0.1:8000
Date: Fri, 06 Mar 2020 05:39:21 GMT, Fri, 06 Mar 2020 05:39:21 GMT
Connection: close
X-Powered-By: PHP/7.2.21
Cache-Control: no-cache, private
Content-Type: application/json
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
{
"id": 1,
"name": "John Doe",
"email": "johndoe@example.com",
"email_verified_at": null,
"created_at": "2020-03-06T02:10:30.000000Z",
"updated_at": "2020-03-06T02:10:30.000000Z"
}
Tokenに誤りがあるとUnauthenticatedエラーが表示されます。
HTTP/1.1 401 Unauthorized
Host: 127.0.0.1:8000
Date: Fri, 06 Mar 2020 05:41:51 GMT, Fri, 06 Mar 2020 05:41:51 GMT
Connection: close
X-Powered-By: PHP/7.2.21
Cache-Control: no-cache, private
Content-Type: application/json
{
"message": "Unauthenticated."
}
Tokenの削除
Tokenを削除したい場合は以下の2つの方法で行うことができます。
// Revoke all tokens...(ユーザのすべてのTokenを削除)
$user->tokens()->delete();
// Revoke a specific token...(ユーザのある特的のTokenを削除)
$user->tokens()->where('id', $id)->delete();
ここまででLaravel AirlockのAPI Tokenを利用した認証方法の動作確認は完了です。