WEBOPIXEL

Laravel+Vue.jsでトークン認証してデータを取得する

Posted: 2018.01.18 / Category: PHP / Tag: ,

LaravelのAPI認証はPassportやJWTなどがありますが、ちょっとVue.jsを使いたいといったときは大げさな気がします。そこでトークン認証でVue.jsを使用してみたいと思います。

Sponsored Link

Laravel 5.4
laravelcollective 5.4 を使用します。

基本のユーザー認証機能を作成

make:authで基本となるユーザー認証関連のファイルを作成します。

$ php artisan make:auth

デフォルトである、ユーザーテーブルのマイグレーションファイルにapi_tokenカラムを追記します。

database/migrations/xxxx_xx_xx_000000_create_users_table.php

Schema::create('users', function (Blueprint $table) {
	$table->increments('id');
	$table->string('name');
	$table->string('email')->unique();
	$table->string('password');
	$table->string('api_token', 60)->unique()->nullable();
	$table->rememberToken();
	$table->timestamps();
});

マイグレーションコマンドでDBテーブルを作成します。

$ php artisan migrate

ログイン&ログアウト時に処理を追加

ログイン時にapi_tokenカラムにランダムな文字列を保存してみます。

app/Http/Controllers/Auth/LoginController.php

protected function authenticated(Request $request, $user)
{
	$user->update(['api_token' => str_random(60)]);
}

public function logout(Request $request)
{
	// api_tokenをnullにする
	$user = $request->user();
	$user->update(['api_token' => null]);

	$this->guard()->logout();

	$request->session()->flush();
	$request->session()->regenerate();

	return redirect('/');
}

config/auth.phpapidrivertokenになっていることを確認。
デフォルトのままなので特に変更の必要はないかと思います。

config/auth.php

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

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

ビュー&JSの設定

レイアウトビューのapp.js読み込み前にapiTokeとして変数作成して、ログインしているユーザーのapi_tokenを入れます。

resources/views/layouts/app.blade.php

<script>
	window.Laravel = {!! json_encode([
		'apiToken' => \Auth::user()->api_token ?? null
	]) !!};
</script>
<script src="{{ asset('js/app.js') }}"></script>

LaravelのVue.jsのデフォルトのHTTPクライアントはaxiosになっているので、axiosのheaderに先ほどのトークンを付与するようなことをします。

resources/assets/js/bootstrap.js

window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + Laravel.apiToken;

試しに使ってみる

これで準備が整いました、簡単なサンプルで試してみます。
ルーテイングはroutes/api.phpにミドルウェアにはauth:apiを指定します。

例えばPostモデルがあったとすれば下記のようにします。

routes/api.php

Route::group(['middleware' => 'auth:api', 'namespace' => 'Api'], function()
{
	Route::get('posts', function(){
        return \App\Post::all();
    });
});

表示するコンポーネントを作成。

resources/assets/js/components/PostList.vue

<template>
	<div class="posts">
		<div v-if="message" class="alert alert-danger">
            {{ message }}
        </div>
        <ul>
            <li v-for="post in posts">
                {{ post.title }}
            </li>
        </ul>
    </div>
</template>

<script>
export default {
	data() {
		return {
			posts: []
		}
	},
	mounted() {
		axios.get('/api/posts')
			.then(res => {
				this.posts = res.data;
			})
			.catch(error => {
				this.message = 'データの取得に失敗しました。';
			});
	}
}
</script>

app.jsにコンポーネント登録

resources/assets/js/app.js

Vue.component('post-list', require('./components/PostsList.vue'));

あとは表示させたいビューに作成したコンポーネントを指定しましょう。

<post-list></post-list>

これで通常のセッションログインした時だけVueコンポーネントで表示できるようになります。

参考サイト
Laravel API Auth with Tokens

COMMENTS

macaron 2018-08-16 22:29 

参考になりました
わざわざ大掛かりなライブラリを導入せず、DBをちょっと弄るくらいなのでいいですね

ところで、マイグレーションファイルのカラムは60なのに、LoginControllerではstr_randomの文字数が100になっていました。

$table->string(‘api_token’, 60)->unique()->nullable();

protected function authenticated(Request $request, $user)
{
$user->update([‘api_token’ => str_random(100)]);
}

webOpixel 2018-08-17 15:03 

macaronさんコメントありがとうございます。
修正しました。

LEAVE A REPLY

コードを書く場合は<pre>で囲んでください。