最近流行りの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でのログイン機能の実装は完了です!!
間違っている点、もっと良いやり方がありましたらご指摘頂けると嬉しいです