[お試し] Laravel Airlockによる認証つきAPI

# はじめに
先日Laravel 7が公開されたのでリリースノートを読んでいたら、新機能の一つにAirlockなるものが。Introductionによると…

> Laravel Airlock provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs.

トークンを付与するだけで認証できちゃうお手軽APIが作れそう！ということで、概ねドキュメント通りにやったお試し記事です。チュートリアル的にお読みいただければ幸いです。各作業に参照したドキュメントへのリンクを貼ったので、詳細の確認や、うまく動かないときはそちらをご覧ください。

試したときのバージョンは以下です。

* Laravel 7.0.4
* Airlock 1.0.0

チュートリアル的に、ということでLaravelのインストールから始めます。なので[Airlockのインストール](#airlockのインストール)までは、今まで通りのLaravelの構築作業です。

# Laravelのインストール

お決まりのcomposer create-projectをターミナルで。 [（ドキュメント）](https://laravel.com/docs/7.x/installation#installing-laravel)

```sh
$ composer create-project --prefer-dist プロジェクト名
```

コマンドを実行したディレクトリにプロジェクト名のフォルダができます。以下、コマンドは全て、このプロジェクト名のディレクトリで実行してます。

# データベースの設定

認証するからにはユーザ情報が必要なのでデータベースの設定をします。mysqlなりなんなりとお好きなものをいつも通りに。

一例としてsqliteでやってみます。　[（ドキュメント）](https://laravel.com/docs/7.x/database#configuration)

```.env``` の ```DB_CONNECTION```で設定できます。

```
# DB_CONNECTION=mysql <-デフォルトのmysqlから変更します
DB_CONNECTION=sqlite
```

sqliteのファイルは、デフォルトだと```database/database.sqlite```らしいのでそこに空ファイルを作ります。ドキュメント通りにtouchが楽ですね。

```sh
$ touch database/database.sqlite
```

# サーバの起動

今回はお試しなので、付属の簡易サーバを使います。ドキュメントはインストールのものと同じ章の下の方です。 [（ドキュメント）](https://laravel.com/docs/7.x/installation#installing-laravel)

```sh
$ php artisan serve
```

これで```http://localhost:8000/```でLaravelにアクセスできるようになりました。ポート番号は実行の環境によっては違うかもしれないので、コマンドの実行結果を確認してください。

こんなページです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/91723050-7732-3233-87a0-cf1f20cefc3a.png)



# ユーザ作成

認証するためのユーザを登録するための機能を作ります。今回はLaravelへおんぶにだっこでいきます。 [（ドキュメント）]
(https://laravel.com/docs/7.x/authentication#introduction)

```sh
$ composer require laravel/ui
$ php artisan ui vue --auth
$ npm install # vueで画面を表示するのでinstallして、と↑のコマンド終わりに言われます
$ npm run dev
```
あとは```http://localhost:8000/register```にアクセスすれば、お決まりのユーザ登録ページが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/10d3a6ca-0a24-d600-3d91-73d4fda23a06.png)

ユーザを作成して```http://localhost:8000/home```にアクセスできればOKです。右上に登録したユーザ名が表示されるはず（今回はadminで登録しました）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/ca34fe6b-8340-0bd3-8fcf-1884916252d6.png)

これで認証用のユーザを作成できました。

# Airlockのインストール

ここからがいよいよ本題。Airlockのインストールを始めます。といってもドキュメント通りです。　[（ドキュメント）](https://laravel.com/docs/7.x/airlock#installation)

```sh
$ composer require laravel/airlock
$ php artisan vendor:publish --provider="Laravel\Airlock\AirlockServiceProvider"
$ php artisan migrate
```

ここでデータベースにトークン管理用のテーブルが作成されます。今回はsqliteを使ったのでDB Browser for SQLiteで閲覧した図です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/3cf5d04b-3b21-7b90-e99b-eab6b78c7a1d.png)

# トークンとユーザの関連付け

トークンとユーザを関連付けるために```app/User.php```へ設定を追加します。ドキュメントではクラス外にuseしてますが、説明が楽なのでフルパスで書いちゃいます（さぼり）　[（ドキュメント）](https://laravel.com/docs/7.x/airlock#issuing-api-tokens)

```php
class User extends Authenticatable
{
    // クラス先頭にあるuseの後ろに追加します。
    use Notifiable, \Laravel\Airlock\HasApiTokens;
...
```

# トークン生成用のページ作成

公式ドキュメントによると```$user->createToken('トークンの名前'):```でトークンを発行できるのだそうです。　 [（ドキュメント）](https://laravel.com/docs/7.x/airlock#issuing-api-tokens)

今回はユーザ作成をブラウザ上でやりましたので、同じくブラウザ上でトークンを生成する機能を作ります。お試しなのでなるべく簡単に、ということでルーティングの設定に直接書いてしまいます（さぼり その2）。

どこでもいいんですが、今回は```routes/web.php```の一番下に追加しました。アクセスするたびにトークンを生成するので、今回は```/reset```という名前にしました。

```php
Route::get("/reset", function() {
    // 現在ログインしているユーザを取得
    $user = \Auth::user();

    // アクセスするたびにトークンが増え続けるので先に削除
    $user->tokens()->delete();

    // トークン生成。データベースに保存されます。
    $token = $user->createToken("token-name");

    // 生成したトークンを表示
    return response($token->plainTextToken);
});
```

これで```http://localhost:8000/reset```とブラウザにアクセスすると、生成したトークンが表示されます。↑のコードの通り、味も素っ気もない、ただ1行でるだけです。このコードはAPI呼び出しに必要になるので大事に取っておいてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/ec5ad556-1da5-4be3-5776-9ba17926aeb6.png)

データーベースにもトークンが保存されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/eda75610-98d0-7e63-1170-c855a24cec7b.png)


# 認証つきAPIの作成

これでトークンを発行できるようになりました。では、トークンでアクセスするAPIを作成します。お試しなので！またもやルーティングに直接書いちゃいます！！ [（ドキュメント）](https://laravel.com/docs/7.x/airlock#token-abilities)

今回はapiなので```routes/api.php```に記述します。ミドルウェアに```auth:airlock```を指定するのがミソ。

```php
Route::middleware("auth:airlock")->get("check", function () {
    return response("valid token");
});
```

```http://localhost:8000/api/check```にアクセスして認証が通れば```valid token ```と返ってくるはず。

# 認証つきAPI呼び出し

これで準備が整いました。あとはアクセスするだけです。生成したトークンをヘッダの```Authentication```で指定して叩きます。大事に取っておいて、と言ったのでなくした人はいないと思いますが、もしトークンをなくしたらもう一度```http://localhost:8000/reset```にアクセスして生成してください。

今回はcurlで叩いてみます。無事```valid token```とかえってこれば成功です。

```sh
$ curl -X GET http://localhost:8000/api/ -H "Authorization: Bearer 生成したトークン
```

[トークン生成のドキュメント](https://laravel.com/docs/7.x/airlock#issuing-api-tokens)に書いてあるとおり、```Bearer```の指定を忘れずに。はい、もちろん、忘れてドハマリしましました。

対応するトークンの```last_used_at```に実行した日時が保存されますので、それを確認するのも運用時に役立ちそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/72626650-83c6-0207-adad-5a2ed2940afb.png)


# おわりに

思った以上に簡単に認証つきAPIが作れました。ほとんどコマンドを叩くだけ…
「誰でもアクセスできるようにはしたくない、とはいえ、ごつい認証が欲しいほどでも」というときに使えそうです。

他にもSPA向きの構築や、認可の仕組み（Token Abilities）もあるそうなので、いろいろ便利そうな機能です。

# 追記

SPAについて投稿しました！　[こちら](https://qiita.com/cranpun/items/8dce7e0afce70c5d228c)