PHP
vue.js
OAuth認証
nuxt.js
laravel5.5

vue.js (Nuxt.js)とlaravelPassportを使ってSPAでのログイン機能を実装してみた

最近流行りのvue.jsのフレームワークNuxt.js(ナクストと読むらしい)でSPAを作っているのですが
その際、laravelのAPI認証ライブラリ「laravelPassport」を使ってログイン機能を実装したのでご紹介したいと思います。
1-6の手順は公式:https://readouble.com/laravel/5.5/ja/passport.html に書いてあります

フレームワーク

nuxt.js フロントサイド
laravel 5.5 サーバーサイド

ライブラリ

laravel/passport": "4.0"
barryvdh/laravel-cors(インストール方法については解説を省きます)

サーバーサイドの実装

1.laravel/passportをインストールする

※ 私の環境はlaravel5.5のためpassportが4.0しか入りませんでした。。。

composer require laravel/passport:4.0

2.laravel/passportで使用するテーブルを作成する

vendor/laravel/passport/database/migrationsにmigrationファイルがありました
vender配下のライブラリのマイグレーションを実行する方法がわからなかったので コピーしてdatabase/migrations移動させてから実行しちゃいました。。。もっといい方法があるはず

php artisan migrate

以下5つのテーブルが追加されます
・oauth_access_tokens
・oauth_auth_codes
・oauth_clients
・oauth_personal_access_clients
・oauth_refresh_tokens

3.認証に必要なシークレットキーを生成する

フロント側からサーバーサイドにアクセストークンを取得しに行く時に必要になります
このコマンドを実行すると先程生成されたoauth_clientsテーブルにデータが生成されます

php artisan passport:install

4.UserモデルにLaravel\Passport\HasApiTokensトレイトを追加

<?php

namespace App\Models;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

5.AuthServiceProviderに以下を追加

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{

    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];


    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}

6.config/auth.phpに以下を追加

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

7.config配下をいじったのでキャッシュクリア

php artisan config:cache

※ CROSSドメイン対応も行う必要がありますが、手順はに関しては今回は解説していません。必要に応じて設定をお願いします

以上でサーバーサイドの準備は完了です!

フロントサイドの実装

※ユーザー新規登録機能の実装の説明は省略します
username、passwordでログインします

1.アクセストークンを取得するaxiosを準備する

/oauth/tokenに以下のデータpostすることでアクセストークンを取得できます

grant_type: 'password',           パスワード認証モードを指定
client_id: '2',                   パスワード認証の場合2を指定する
client_secret: 'シークレットキー',     サーバーサイドで生成してシークレットキー
username: this.username,          userテーブルのusername
password: this.password,          userテーブルのpassword
<template>
    <main id="registrationForm">
        <h1>
            ログイン
        </h1>
        <label>メール</label><br>
        <input v-model="username"><br>
        <label>パスワード</label><br>
        <input v-model="password"><br>

        <button v-on:click="Login">ログイン</button>
    </main>
</template>

<script>
import axios from 'axios';

export default {
    data () {
        return {
          username: '',
          password: '',
        }
    },
    methods: {
        getHeaders(token) {
          return {
            Authorization: `Bearer ${token}`
          }
        },
        Login() {
            const postData = {
                grant_type: 'password',
                client_id: '2',
                client_secret: 'シークレットキー',
                username: this.username,
                password: this.password,
            }
            console.log(postData)
          axios.post('http://localhost:4242/api/oauth/token', postData)
            .then(response => {

                //取得したアクセストークンをヘッダーに入れる
                const headers = this.getHeaders(response.data.access_token)
                axios.defaults.headers.common['Authorization'] = headers.Authorization;
            })
            .catch(error => {
                console.log('ログインに失敗しました')
            })
        },
    }
}
</script>

2.ログイン後のパスにアクセスする

取得したアクセストークンをheaderに入れることで
->middleware(‘auth:api’)と指定したパスにアクセスできる用になります

Route::get('user/', 'Api\UserController@index')->middleware('auth:api');

以上でAPIでのログイン機能の実装は完了です!!
間違っている点、もっと良いやり方がありましたらご指摘頂けると嬉しいです