Recent Posts
Archives
Categories
Simple way to configure vue.js (axios, pinia) to work with Laravel Sanctum Token based auth
Laravel Sanctum gives a simple mechanism of authentication for SPAs (Single Page Applications). There are basically two ways Sanctum can be used.
1. API Tokens: Sanctum can generate token for an authenticated user and that token can be used everytime for subsequent requests.
2. SPA Authentication: For this functionality, Sanctum avoids the use of tokens and, instead, relies on Laravel’s native session-based authentication using cookies.
It is not mandatory two use both functionalities at the same time. It depends on the use case. If you are developing an application where backend and frontend will be stored under same domain, then SPA Authentication is good. However, for headless development, when you use Laravel only for API, then you can only use the first function to generate token.
For one of my application I used Sanctum to generate token after a successful login. For front end I used vue.js with axios and pinia packages. After a successful login, I stored the token in pinia storage and then use it for every subsequent axios requests.
//laravel login controller returns the token after successful login
return response()->json([
'token' => $admin->createToken('laravel_api_token')->plainTextToken
]);
import axios from "axios";
import { useAuthStore } from "../stores/auth";
const api = axios.create({
baseURL: "http://127.0.0.1:8000",
});
//The following codes ensure that token is passed with header for all axios requests
api.interceptors.request.use(
(config) => {
const store = useAuthStore()
//suppose token is already stored after login
const auth = store.token ? `Bearer ${store.token}` : null;
config.headers['Authorization'] = auth;
return config;
});
In the routes file I used meta to set auth: true, and then used router.beforeEach to check every route if auth is set and and user is logged in or not.
const routes = [
{
meta: {
title: 'Dashboard',
auth: true
},
path: '/dashboard',
name: 'dashboard',
component: Home
},
..... //other routes
]
const router = createRouter({
history: createWebHashHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
return savedPosition || { top: 0 }
}
})
router.beforeEach(async (to, from) => {
const store = useAuthStore();
await store.fetchUser(); //each time we fetch user info from backend to ensure session is still valid
// each route is checked if authentication is required and user is logged in
if (to.meta.auth && !store.isLoggedIn) {
return {
name: "login",
query: {
redirect: to.fullPath,
},
}
}else if(to.meta.guest && store.isLoggedIn){
return {
name: "dashboard"
}
}
});