Edited at

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

More than 1 year has passed since last update.

最近流行りの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でのログイン機能の実装は完了です!!

間違っている点、もっと良いやり方がありましたらご指摘頂けると嬉しいです