Vue + axios でLaravelにユーザー認証する(ダウンロード可)

さてさて、私は長年Laravelを使って開発をしているのですが、その理由として「デフォルトで多数の機能を備えている」というものが挙げられます。

そして、その中でも特によく使う機能が「ユーザー認証」です。

私が開発の仕事を始めたことは、まだしっかりとしたフレームワークは存在していなかったので、ユーザー認証が必要となればセッション値の持たせかたをこうして、テーブル構造はこんな風にして・・・なんて、それだけで膨大なコードを書いたものですが、これがLaravelだとコマンド一発(正確にはマイグレーションするので2発)で認証機能が実装できてしまいます。😊✨

ただ、このLaravelのユーザー認証。
皆さんも知っての通りデフォルトではHTTP送信をするようになっているので、Ajaxを使ってログインさせたい場合には自分自身で実装をする必要があります。

ということで、今回はちょっとだけ初心に帰って基本中の基本、ユーザー認証をAjax(axios + Vue)で実装する方法をご紹介します。

ぜひ皆さんのお役にたてると嬉しいです!(最後に今回実際に開発したbladeファイルをダウンロードできます

「Ajaxがここまでメジャーになるとは思っていませんでした(笑)」

開発環境: Laravel 5.8, Vue 2.6, axios 0.18

前提として

php artisan make:auth でユーザー認証機能をつくっていることが前提になります。

もしまだLaravelに認証機能をつくっていない場合は先に以下の以下のページを参考にして準備しておいてください。

【Laravel5.6】インストール直後にやること3点

また、ログインするユーザーデータがないとテストできませんので、Seederなどで以下のようなテスト・ユーザーをつくっておいてください。(これも上のページで紹介しています)

こんな感じです↓↓↓

ログインフォームをつくる

まずはログインフォームです。
シンプルにしたいので、bootstrap 4cdnで読み込んで使うことにします。

<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <div id="app">
        <div class="row">
            <div class="offset-4 col-md-4">
                <br>
                <h4>ログイン</h4>
                <br>
                <div class="form-group">
                    <label>Email</label>
                    <input type="text" class="form-control">
                </div>
                <div class="form-group">
                    <label>パスワード</label>
                    <input type="password" class="form-control">
                </div>
                <div class="form-group">
                    <label>
                        <input type="checkbox"> 次回から省略
                    </label>
                </div>
                <div class="form-group">
                    <button type="button" class="btn btn-dark btn-block">ログイン</button>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

実際に実行したものがこちら。(bootstrapも長らくお世話になってます。^^)

Vueとaxiosが使えるようにする

実際に開発を進めて行く前に、今回必要になるJavaScriptライブラリ(Vue.js & axios)を使えるようにしておきます。

<!-- 省略 -->

</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
<script>

    new Vue({
        el: '#app'
    });

</script>
@endsection

送信データをバインディングする

さらに、Ajax送信するデータを管理しやすいようにVueでインプットタグに以下3つのデータをバインディングしておきます。

  • email
  • password
  • remember

実際のコードはこうなります。

(JavaScript部分)

new Vue({
    el: '#app',
    data: {
        email: '',
        password: '',
        remember: false
    }
});

(HTML部分)

<div class="form-group">
    <label>Email</label>
    <input type="text" class="form-control" v-model="email">
</div>
<div class="form-group">
    <label>パスワード</label>
    <input type="password" class="form-control" v-model="password">
</div>
<div class="form-group">
    <label>
        <input type="checkbox" v-model="remember"> 次回から省略
    </label>
</div>

ログイン・ボタンにクリックイベントをつける

続いて、「ログイン」ボタンをクリックしたときのイベントを実行できるようにします。

まず、ボタンに@click=""で実行するメソッドを指定しましょう。

<button type="button" class="btn btn-dark btn-block" @click="login">ログイン</button>

そして、Vueにメソッドを追加します。

new Vue({

    // 省略

    methods: {
        login: function(){

            // ここでAjax通信

        }
    }
});

Ajax通信する部分をつくる

では、今回のメイン部分「Ajax通信」をaxiosで実行できるようにします。
まずは実際のコードから。

login: function(){

    var url = '/login';
    var params = {
        email: this.email,
        password: this.password,
        remember: this.remember
    };
    axios.post(url, params)
        .then(function(response){

            // ログイン成功!😊✨

        })
        .catch(function(error){

            // ログイン失敗..😫💦

        });

}

やっていることは、先ほどバインディングしたデータをaxiosで送信しているだけですが、注目してほしいのはurlの部分です。

これは元々Laravelが用意してくれているログイン用のURLです。つまり、ログイン認証のコントローラーを独自に作る必要はないんですね。

エラーを表示できるようにする

Laravelが用意してくれているコントローラーを使うと言ってもきちんとエラーがあればjson形式で返してくれますので、この部分のコードを見ていきましょう。

new Vue({
    // 省略
    data: {
        // 省略
        errors: {}
    },
    methods: {
        login: function(){

            this.errors = {};
            var self = this;

            // 省略

まず、dataの中にエラーメッセージが格納される変数errorsを登録します。

そして、そのerrorsは送信するたびに初期化するようにし、さらにfunction()内からでも変数へアクセスできるよう、thisselfに格納しておきます。(ES6を使えばこんな苦労もないのですが、なにせIEが…いや、これ以上は何も言いますまい ToT)

では、変数errorsにエラーメッセージが格納されるようにcatch()部分をつくっていきましょう。

axios.post(url, params)
    .then(function(response){

        // ログイン成功

    })
    .catch(function(error){

        var responseErrors = error.response.data.errors;
        var errors = {};

        for(var key in responseErrors) {

            errors[key] = responseErrors[key][0];

        }

        self.errors = errors;

    });

やっているのは、axiosがAjax通信で取得したエラーメッセージerrorsに格納しているだけです。なお、先ほども書きましたがスコープが違ってくるのでアロー関数を使っていない限りselfを使って変数にアクセスをしましょう。

※ なお、なぜ直接self.errors[key] = 'xxxx';としないかというと、リアクションが起動されない(つまり表示がリアルタイムに変更できない)からです。詳しくは、Vue本家のリアクティブの追求をご覧ください。

エラーメッセージのコードができたら、最後に表示部分です。

<div class="form-group">
    <label>Email</label>
    <input type="text" class="form-control" v-model="email">
    <div class="alert alert-danger" v-text="errors.email" v-if="errors.email"></div>
</div>
<div class="form-group">
    <label>パスワード</label>
    <input type="password" class="form-control" v-model="password">
    <div class="alert alert-danger" v-text="errors.password" v-if="errors.password"></div>
</div>

これで完了です。
ではテストでエラーを発生させてみましょう!

はい!うまくいきました。

※ ただし、このエラメッセージは日本語化した後のものです。詳しくは【Laravel5.6】インストール直後にやること3点 : バリデーションをご覧ください。

ログインに成功したらリダイレクト

では、最後にログインが成功した時にLaravelと同じく/homeへリダイレクトする部分を追加して終了です。

axios.post(url, params)
    .then(function(response){

        location.href = '/home';

    })
    .catch(function(error){

        // 省略

    });

…と言ってもlocation.hrefを追加するだけですね(笑)

実際に実行したものがこちらです。

今回は以上です!

ソースコードをダウンロード

今回実際に開発したコードを以下からダウンロードすることができます。
※ ただし、LaravelのBladeファイルなので、ご自身でコントローラーやルーティングの設定が必要です。

Vue + axios でLaravelにユーザー認証

おわりに

今回の一番の特徴としては、「ログイン用のコントローラーはLaravelのものを使うことができる」という部分です。

元々あるものを使うことで開発効率がグッ!っと上がりますし、バグの発生も少なくすることができるでしょう。

また、ログインをAjaxにする意義ですが、まずHTTP送信しなくてよいので、ユーザー側からすると表示時間も短縮できますし、なにより一回一回ページの上部に強制的に移動させられなくなるためメリットはそれなりに多いでしょう。(ただし、Ajaxの場合はフォームが縦に長い場合、逆にエラー箇所にスクロールさせないと状況がわからなくなったりもするので一長一短はありますね。)

ということで、今回はVue + axios + LaravelでAjaxログインをやってみました。

ぜひ皆さんも参考にしてみてくださいね。

ではでは〜!