[お試し] Laravel AirlockのAPIにSPAからアクセス

# はじめに

前回の記事で[LarvelのAirlockで認証つきAPI](https://qiita.com/cranpun/items/110d193699d7029ed59f)を作ったので、今度はSPAから認証つきでアクセスしてみます。

# ドメインの設定

最初にSPAを設置しているドメインを設定する必要があります。```config/airlock.php```の```stateful```に記述します。ただ初期設定が```.env```の```AIRLOCK_STATEFUL_DOMAINS```の値が設定されます。ということで以下のように記述します。

```
AIRLOCK_STATEFUL_DOMAINS="localhost"
```

…まあデフォルトの値がlocalhostなので、localhostで試すのであればわざわざ設定する必要はなかったりします。

# Airlock ミドルウェアの登録

アクセス中のブラウザで確立したセッションで認証ができる＝SPAのコードでは認証について意識せずにアクセスできるという仕掛けらしいです。　[（ドキュメント）](https://laravel.com/docs/master/airlock#spa-authentication)

```app/Http/Kernel.php```のapiのmiddlewareにAirlock のミドルウェアを登録します。

```php
    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [ ... ],
        'api' => [
            // ↓1行追加します
            \Laravel\Airlock\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:60,1',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];
```

# SPAからアクセスするAPIを定義

middlewareに```auth:middleware```を指定します。前回の投稿のままから変更ありません。ルーティングの設定に直接書いちゃうお手軽APIです。

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

正しくアクセスできれば「valid token」と返ってきます。Airlockならでは、はここでおしまいです。あとはいつもどおりのLaravel-mix。

# フロントエンドからAPIを呼び出す

前記事でLaravel備え付けのユーザ登録の機能を生成したときにVueの設定も一式生成されているのでそれを使ってみます。

## Vueのコンポーネントを表示

ログインして最初に表示されるページは```resources/views/home.blade.php```の内容になります。ここにVueのコンポーネントを表示する要素を用意します。　ドキュメントは…ちょっとずれてますが、せっかくなのでbladeのものを。　[（ドキュメント）](https://laravel.com/docs/master/blade)

```html
@extends('layouts.app')

@section('content')
<div class="container">
...
</div>
<div id="frontend"></div>
@endsection

```

idを```frontend```としました。

## Vueのコンポーネントを作成

Vueのコンポーネントは```resources/js/components/ExampleComponent.vue```に生成されています。

ここに「APIを呼び出すボタン」「呼び出した結果を表示する場所」を作成します。ここのドキュメントは…もはやVueなのでVueのドキュメントをのせておきます。 単一ファイルのところとかが参考になるでしょうか？　[（ドキュメント）](https://jp.vuejs.org/v2/guide/single-file-components.html)

```vue
<template>
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-8">
        <div class="card">
          <div class="card-header">Example Component</div>

          <div class="card-body">
            <!-- これがAPIを呼び出すボタン。押すとcheckというmethodを呼び出す。 -->
            <button id="btn-check" @click="check" class="btn btn-primary">check</button>

            <!-- これが表示するための場所。checkresultというdataに設定した内容を表示 -->
            <div id="prot-check" class="alert alert-info mt-2">{{ checkresult }}</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data: () => {
    return {
      // APIの結果を表示するdata
      checkresult: "before check"
    };
  },
  methods: {
    // APIを呼び出す処理。
    async check() {
      try {
        const res = await axios.get("/api/check");
        this.checkresult = res.data;
      } catch (error) {
        console.error(error);
      }
    }
  },
  mounted() {
    console.log("Component mounted.");
  }
};
</script>
```

書き終わったらwebpackして読み込むjavascriptのファイルを生成します。
コンソールでLaravelの一番上のディレクトリで```npm run dev```！

# 出来上がりの画面

できあがり。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/c46e8615-15ba-51e5-f32e-b5c3dd88efb7.png)

checkボタンを押すと…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/9c3fc42b-e157-1e57-e88a-b074ffed6975.png)

valid tokenになればOKです。

# おわりに

Airlockならではなのはたった2箇所、middlewareの登録と、ルーティングのmiddlewareに```auth:airlock```を指定するだけ。やってみたらものすごく簡単でした。