Laravel JWT Auth with Vue.js

This post documents using Laravel to build JSON Web Token based authentication with a Vue.js user interface.

A fresh install of Laravel 5.2 for local development is required. Head over to the Laravel 5.2 docs to get setup with Composer and Laravel as needed. This post contains some info on how I installed Laravel 5.2 on Windows. Once Laravel 5.2 is installed, the database created and the .env file updated to connect to it, run the migration to create the users table.

php artisan migrate

User Model

One of the first things I like to do is create a Models folder and move the User model into it. To organize models within their own directory, start by creating a folder named Models in the app directory and move the User model into it.

mkdir app/Models

mv app/User.php app/Models

Edit app/Models/User.php, change the App namespace to App\Models.


namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable

  • Throughout this tutorial you will encounter an ellipsis … in the code examples. These are not a part of the code and are there only to denote code that is being skipped and not applicable to the example. To view the entire file, examine the source code.

Edit, config/auth.php. Update the authentication drivers user provider for the App\Models\User namespace change as follows.

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,


Laravel Elixir Vueify

Using NPM, install the dependencies including laravel-elixer and gulp that should already be defined in the package.json file.

npm install

Install the Laravel Elixir and the Browserify Vueify plugin wrapper, laravel-elixir-vueify. This node package also includes Vue.js.

For Laravel Elixer 5
npm install laravel-elixir-vueify@1.0.6 --save-dev

Laravel Elixir is a build tool wrapper for Gulp. To use laravel-elixir-vueify, require laravel-elixir-vueify and update the elixir call with mix.browserify in the gulpfile.js as follows.

elixir(function(mix) {

elixir(function(mix) {

Create a resources/js folder for the JavaScript.

mkdir resources/assets/js

Create a resources/js/app.js JavaScript file.

touch resources/assets/js/app.js

Test the gulp build. A browserified app.js file that includes an external source map file should get compiled and written to public/js/app.js. The pre-existing app.scss Sass file should also get compiled.

Default Gulp task output
Default Gulp task output

Vue Router and Components

Install the router for Vue.js.

npm install vue-router --save-dev

Create a resources/assets/components folder and add an empty App.vue, Dashboard.vue, Home.vue, Register.vue and Signin.vue component.

mkdir resources/assets/components

touch resources/assets/components/App.vue

touch resources/assets/components/Dashboard.vue

touch resources/assets/components/Home.vue

touch resources/assets/components/Register.vue

touch resources/assets/components/Signin.vue

Add the following code to the empty App.vue file which will be the base layout component.

    <div class="panel panel-default">
        <div class="panel-heading">
                <ul class="list-inline">
                    <li><a v-link="{ name: 'home' }">Home</a></li>
                    <li class="pull-right">
                        <a v-link="{ name: 'register' }">Register</a>
        <div class="panel-body">

Add the following code to the empty Home.vue file. The content in this template will populate the App.vue router-view element by default.

    <h1>Laravel 5</h1>

Add the following code to the empty Register.vue file for the user account creation form.

    <div class="alert alert-danger" v-if="error && !success">
        <p>There was an error, unable to complete registration.</p>
    <div class="alert alert-success" v-if="success">
        <p>Registration completed. You can now sign in.</p>
    <form autocomplete="off" v-on:submit="register" v-if="!success">
        <div class="form-group" v-bind:class="{ 'has-error': error && response.username }">
            <label for="name">Name</label>
            <input type="text" id="name" class="form-control" v-model="name" required>
            <span class="help-block" v-if="error &&">{{ }}</span>
        <div class="form-group" v-bind:class="{ 'has-error': error && }">
            <label for="email">E-mail</label>
            <input type="email" id="email" class="form-control" placeholder="" v-model="email" required>
            <span class="help-block" v-if="error &&">{{ }}</span>
        <div class="form-group" v-bind:class="{ 'has-error': error && response.password }">
            <label for="password">Password</label>
            <input type="password" id="password" class="form-control" v-model="password" required>
            <span class="help-block" v-if="error && response.password">{{ response.password }}</span>
        <button type="submit" class="btn btn-default">Submit</button>

Add the following code to the empty app.js file to require vue, the vue-router, import vue components, setup the router. Export Vue and the router to allow modules to import them.

var Vue = require('vue');
var VueRouter = require('vue-router');

import App from '../components/App.vue';
import Dashboard from '../components/Dashboard.vue';
import Home from '../components/Home.vue';
import Register from '../components/Register.vue';
import Signin from '../components/Signin.vue';


export default Vue;
export var router = new VueRouter{
    '/': {
        name: 'home',
        component: Home
    '/register': {
        name: 'register',
        component: Register

router.start(App, '#app');

Web Page

Edit the resources/views/welcome.blade.php template.

Replace the entire contents of the file with this markup.

<!DOCTYPE html>
    <meta charset="utf-8">
    <meta name="csrf-token" content="{!! csrf_token() !!}">

    <link href="" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <div class="container">
        <div id="app"></div>
    <script src="/js/app.js"></script>

Now is a good time to test that everything builds and you have a Bootstrap styled page with with links to Home and Register in a horizontal navigation bar and a content panel under it with “Laravel 5” heading text. Select the Register link to diplay the form in the content panel.

Laravel JWT Auth Vuejs User Registration Form
New User Registration Form

The next page covers Vue Resource for request handling, Form Request Validation, API authorization with JWT Auth, User endpoint and Sign in.

Published by

Jim Frenette

Web Developer - views here are my own except those taken from people more clever than me.

Loading Disqus Comments ...
Loading Facebook Comments ...