Laravel JWT Auth with Vue.js

Remaining Front End Components

Add the following code to the empty Signin.vue file.

Signin.vue
<template>
    <div class="alert alert-danger" v-if="error">
        <p>There was an error, unable to sign in with those credentials.</p>
    </div>
    <form autocomplete="off" v-on:submit="signin">
        <div class="form-group">
            <label for="email">E-mail</label>
            <input type="email" id="email" class="form-control" placeholder="gavin.belson@hooli.com" v-model="email" required>
        </div>
        <div class="form-group">
            <label for="password">Password</label>
            <input type="password" id="password" class="form-control" v-model="password" required>
        </div>
        <button type="submit" class="btn btn-default">Sign in</button>
    </form>
</template>
<script>
import auth from '../js/auth.js';

export default {
    data() {
            return {
                email: null,
                password: null,
                error: false
            }
        },
        methods: {
            signin(event) {
                event.preventDefault()
                auth.signin(this, this.email, this.password)
            }
        }
}
</script>

Add the following code to the empty Dashboard.vue file. The content in this template will populate the App.vue router-view element when the user is authenticated.

Dashboard.vue
<template>
    <h1>Laravel 5 - Dashboard</h1>
</template>

Update auth.js as follows to handle all of the authorization functions.

auth.js
...

export default {
    user: {
        authenticated: false,
        profile: null
    },
    check() {
        if (localStorage.getItem('id_token') !== null) {
            Vue.http.get(
                'api/user',
            ).then(response => {
                this.user.authenticated = true
                this.user.profile = response.data.data
            })
        }
    },
    register(context, name, email, password) {
        Vue.http.post(
            'api/register',
            {
                name: name,
                email: email,
                password: password
            }
        ).then(response => {
            context.success = true
        }, response => {
            context.response = response.data
            context.error = true
        })
    },
    signin(context, email, password) {
        Vue.http.post(
            'api/signin',
            {
                email: email,
                password: password
            }
        ).then(response => {
            context.error = false
            localStorage.setItem('id_token', response.data.meta.token)
            Vue.http.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('id_token')

            this.user.authenticated = true
            this.user.profile = response.data.data

            router.go({
                name: 'dashboard'
            })
        }, response => {
            context.error = true
        })
    },
    signout() {
        localStorage.removeItem('id_token')
        this.user.authenticated = false
        this.user.profile = null

        router.go({
            name: 'home'
        })
    }
}

Update the router.map in app.js to include the Dashboard and Signin components.

app.js
...

router.map({
    '/': {
        name: 'home',
        component: Home
    },
    '/dashboard': {
        name: 'dashboard',
        component: Dashboard
    },
    '/register': {
        name: 'register',
        component: Register
    },
    '/signin': {
        name: 'signin',
        component: Signin
    },
});

1. Update the App.vue navigation inside the nav so the Register link is only available when applicable. Add a Sign in and Sign out link along with a list item to show the users name when signed in.

2. At the bottom of the App.vue file add a script to bind the auth.js methods.

App.vue
...

<nav>
    <ul class="list-inline">
        <li><a v-link="{ name: 'home' }">Home</a></li>
        <li class="pull-right" v-if="!auth.user.authenticated">
            <a v-link="{ name: 'register' }">Register</a>
        </li>
        <li class="pull-right" v-if="!auth.user.authenticated">
            <a v-link="{ name: 'signin' }">Sign in</a>
        </li>
        <li class="pull-right" v-if="auth.user.authenticated">
            <a href="#" v-on:click="signout">Sign out</a>
        </li>
        <li class="pull-right" v-if="auth.user.authenticated">
            Hi, {{ auth.user.profile.name }}
        </li>
    </ul>
</nav>

...

<script>
import auth from '../js/auth.js'

export default {
    data() {
            return {
                auth: auth
            }
        },
        methods: {
            signout() {
                auth.signout()
            }
        },
        ready() {
            auth.check()
        }
}
</script>

That’s It!

Rebuild the app with the gulp command and give it a test drive.

gulp

Versions that were used in this tutorial.

  • Laravel 5.2
  • Laravel Elixir Vueify v1.0.6
  • JWT Auth v0.5.9
  • Vue v1.0.26
  • Vue Resource v1.0.1
  • Vue Router v0.7.13

Source Code

Published by

Jim Frenette

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