API Authentication Using Laravel 9 Sanctum and Vue js 3 Part 2
In the second part of this tutorial, we are going to add routes to our API Authentication system and we will add also the main component.
Create the vue routes
Inside the router folder, we add a new file index.js here we define all of our routes.
import { createRouter, createWebHashHistory } from "vue-router";
import Home from "@/components/Home.vue";
import Login from "@/components/Login.vue";
import { useAuthStore } from '@/stores/useAuthStore.js';
function checkIfLogged() {
const store = useAuthStore();
if (!store.getUser) return '/login';
}
function checkIfNotLogged() {
const store = useAuthStore();
if (store.getUser) return '/';
}
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/",
name: "home",
component: Home,
beforeEnter: [checkIfLogged],
},
{
path: "/login",
name: "login",
component: Login,
beforeEnter: [checkIfNotLogged],
},
],
});
export default router;
Create the Header Component
Inside the components folder, we add a new file Header.vue.
<template>
<nav class="navbar navbar-expand-lg navbar-light bg-white rounded-0 shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="#">Laravel Inventory</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item">
<router-link class="nav-link active" aria-current="page" to="/">Home</router-link>
</li>
</ul>
<ul v-if="!store.getUser" class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item">
<router-link class="nav-link" aria-current="page" to="/login">Login</router-link>
</li>
</ul>
<ul v-else class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item">
<router-link class="nav-link" aria-current="page" to="#">
{{ store.getUser.data.name }}
</router-link>
</li>
<li class="nav-item">
<a href="#" class="nav-link" @click="userLogout" style="cursor:pointer">Logout</a>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script setup>
import { useAuthStore } from '@/stores/useAuthStore.js';
import Swal from 'sweetalert2';
import router from '@/router';
const store = useAuthStore();
const userLogout = async () => {
try {
const response = await axios.get('/api/logout', store.getHeaderConfig);
Swal.fire({
icon: 'success',
text: response.data.message,
});
store.clearStoredData();
router.push('/login');
} catch (error) {
console.log(error);
}
}
</script>
<style>
</style>
Create the Main Component
Inside the components folder, we add a new file Main.vue.
<template>
<Header></Header>
<router-view></router-view>
</template>
<script setup>
import Header from './Header.vue';
import { onMounted } from "vue";
import { useAuthStore } from '@/stores/useAuthStore.js';
const store = useAuthStore();
onMounted(() => {
store.setUser();
});
</script>
<style>
</style>
Create the Home Component
Inside the components folder, we add a new file Home.vue.
<template>
<div class="container">
<div class="row my-5">
<div class="col-md-4">
<div class="card">
<div class="card-header">
sidebar
</div>
<div class="card-body">
</div>
</div>
</div>
<div class="col-md-8">
<div class="card">
<div class="card-header">
Logged in!
</div>
<div class="card-body">
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
</script>
<style>
</style>
Create the Login component
Inside the components folder, we add a new file Login.vue.
<template>
<div class="container">
<div class="row my-5">
<div class="col-md-6 mx-auto">
<ul class="list-group my-2" v-for="(errorArray, index) in store.getErrors" :key="index">
<li class="list-group-item bg-danger text-white mb-1" v-for="(error, index) in errorArray" :key="index">
{{error}}
</li>
</ul>
<div class="card">
<div class="card-header bg-white">
<h4 class="text-center">
Login
</h4>
</div>
<div class="card-body">
<div class="form-group mb-3">
<input
type="text"
v-model="data.user.email"
placeholder="Email*" class="form-control">
</div>
<div class="form-group mb-3">
<input
type="password"
v-model="data.user.password"
placeholder="Password*" class="form-control">
</div>
<div class="form-group mb-3">
<button @click="userAuth" class="btn btn-primary btn-sm">
Login
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import Swal from 'sweetalert2';
import router from '@/router';
import { useAuthStore } from '@/stores/useAuthStore.js';
const store = useAuthStore();
const data = reactive({
user: {
email: '',
password: ''
}
});
const userAuth = async () => {
store.clearErrors();
try {
const response = await axios.post('/api/login', data.user);
if(response.data.success){
store.storeUser(response.data.user);
router.push('/');
}else{
Swal.fire({
icon: 'error',
title: 'Oops...',
text: response.data.message,
});
}
} catch (error) {
store.setErrors(error.response.data.errors);
}
}
</script>
<style>
</style>