九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、私は長年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
に認証機能をつくっていない場合は先に以下の以下のページを参考にして準備しておいてください。
また、ログインするユーザーデータがないとテストできませんので、Seeder
などで以下のようなテスト・ユーザーをつくっておいてください。(これも上のページで紹介しています)
こんな感じです↓↓↓
ログインフォームをつくる
まずはログインフォームです。
シンプルにしたいので、bootstrap 4
をcdn
で読み込んで使うことにします。
<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つのデータをバインディングしておきます。
- 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()
内からでも変数へアクセスできるよう、this
をself
に格納しておきます。(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ファイルなので、ご自身でコントローラーやルーティングの設定が必要です。
おわりに
今回の一番の特徴としては、「ログイン用のコントローラーはLaravelのものを使うことができる」という部分です。
元々あるものを使うことで開発効率がグッ!っと上がりますし、バグの発生も少なくすることができるでしょう。
また、ログインをAjaxにする意義ですが、まずHTTP送信しなくてよいので、ユーザー側からすると表示時間も短縮できますし、なにより一回一回ページの上部に強制的に移動させられなくなるためメリットはそれなりに多いでしょう。(ただし、Ajaxの場合はフォームが縦に長い場合、逆にエラー箇所にスクロールさせないと状況がわからなくなったりもするので一長一短はありますね。)
ということで、今回はVue
+ axios
+ Laravel
でAjaxログインをやってみました。
ぜひ皆さんも参考にしてみてくださいね。
ではでは〜!