Laravel 12 + Vue.js 3 Authentication (2026): Full Beginner-Friendly Guide with Real-World Examples
If you’ve built a Laravel + Vue CRUD app and thought:
“Okay… but how do real users log in and stay logged in?”
You’re asking the right question.
Authentication is where most beginners get stuck. Tokens, cookies, CSRF, sessions—it can feel like a foreign language. I remember staring at a 401 Unauthorized error for hours, wondering what I broke.
In this blog, we’ll build authentication the correct, modern way in 2026, using:
- Laravel 12 as the backend
- Vue.js 3 as the frontend
- Laravel Sanctum for authentication
- Session-based auth (simple & secure)
No shortcuts. No skipped steps. Just a clean, understandable flow.
What We’re Building (Clear Goal)
By the end of this tutorial, you will have:
- User registration (Vue form → Laravel)
- User login
- Authenticated user state
- Protected API routes
- Logout
- Vue knowing who is logged in
Real-world analogy
Laravel = office security system
Vue = employee
Sanctum = ID card
Once logged in, the employee can move freely until they log out.
Why Laravel Sanctum? (Beginner Explanation)
Laravel Sanctum handles authentication in two ways:
- SPA authentication (cookies + sessions) ✅ we’ll use this
- API tokens (mobile apps, external clients)
Why SPA auth is perfect for Vue
- No manual token handling
- Secure cookies
- Simple setup
- Officially recommended
In short: less headache, more productivity.
Step 1: Install Laravel Sanctum
From your Laravel project root:
composer require laravel/sanctum
Publish config:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Run migrations:
php artisan migrate
Sanctum is now installed.
Step 2: Configure Sanctum (Very Important)
Open:
config/sanctum.php
Make sure stateful domains include your app:
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'localhost,127.0.0.1'
)),
Update .env
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost
Warning: If this step is wrong, login will work but every request will return 401.
I learned this the hard way.
Step 3: Enable Sanctum Middleware (Laravel 12 Way)
Open:
bootstrap/app.php
Ensure this middleware exists:
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
$middleware->append([
EnsureFrontendRequestsAreStateful::class,
]);
This allows Vue (SPA) to authenticate using cookies.
Step 4: Auth Routes (Backend)
Authentication Controller
Create controller:
php artisan make:controller Api/AuthController
AuthController.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
public function register(Request $request)
{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
Auth::login($user);
return response()->json($user);
}
public function login(Request $request)
{
if (!Auth::attempt($request->only('email', 'password'))) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
return response()->json(Auth::user());
}
public function user(Request $request)
{
return $request->user();
}
public function logout()
{
Auth::logout();
return response()->noContent();
}
}
Step 5: API Routes
Open:
routes/api.php
use App\Http\Controllers\Api\AuthController;
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', [AuthController::class, 'user']);
Route::post('/logout', [AuthController::class, 'logout']);
});
This means:
/useronly works when logged in/logoutonly works when logged in
Step 6: Vue Setup for Authentication
Axios Configuration (CRITICAL)
Open:
resources/js/app.js
import axios from 'axios';
axios.defaults.withCredentials = true;
axios.defaults.baseURL = 'http://localhost:8000';
CSRF Cookie (Required)
Before login/register, Sanctum needs CSRF:
await axios.get('/sanctum/csrf-cookie');
This is mandatory.
Step 7: Vue Auth Component (Login & Register)
Auth.vue
<template>
<div>
<h2>Register</h2>
<input v-model="register.name" placeholder="Name" />
<input v-model="register.email" placeholder="Email" />
<input v-model="register.password" type="password" placeholder="Password" />
<button @click="registerUser">Register</button>
<hr>
<h2>Login</h2>
<input v-model="login.email" placeholder="Email" />
<input v-model="login.password" type="password" placeholder="Password" />
<button @click="loginUser">Login</button>
<hr>
<button @click="getUser">Get Auth User</button>
<button @click="logout">Logout</button>
<pre>{{ user }}</pre>
</div>
</template>
<script setup>
import axios from 'axios'
import { ref } from 'vue'
const register = ref({ name:'', email:'', password:'' })
const login = ref({ email:'', password:'' })
const user = ref(null)
const registerUser = async () => {
await axios.get('/sanctum/csrf-cookie')
user.value = (await axios.post('/api/register', register.value)).data
}
const loginUser = async () => {
await axios.get('/sanctum/csrf-cookie')
user.value = (await axios.post('/api/login', login.value)).data
}
const getUser = async () => {
user.value = (await axios.get('/api/user')).data
}
const logout = async () => {
await axios.post('/api/logout')
user.value = null
}
</script>
Step 8: Protecting Vue Pages
Backend protection
Route::middleware('auth:sanctum')->get('/posts', fn () => Post::all());
Frontend check
if (!user.value) {
// redirect to login
}
Common Beginner Mistakes (Avoid These)
- Forgetting
/sanctum/csrf-cookie - Missing
withCredentials - Wrong session domain
- Trying to manually store tokens
- Using old JWT tutorials
If auth returns 401, check Sanctum config first.
Pro Tip (Real-World Advice)
For SPAs, cookie-based auth is:
- More secure
- Easier to manage
- Officially supported
Only use token auth if:
- Mobile apps
- External API users
Quick Summary
- Laravel Sanctum is the best auth choice in 2026
- Vue handles UI, Laravel handles auth logic
- Cookies + sessions keep users logged in
- Protected routes are easy with
auth:sanctum
Once you understand this flow, authentication stops being scary.
FAQ (Beginner Friendly)
1) Is Sanctum better than JWT?
For SPAs, yes. Less complexity, better security.
2) Can I add roles (admin/user)?
Yes. Add a role column and check it with middleware.
3) Can I deploy this to production?
Yes. Just update domain settings and run npm run build.
Projects to explore next
Source-code projects from the KritiMyantra catalogue. Check each project's details before buying.
Flask Authentication System (Free Version) - Kritim Yantra
🛠 Features✔ Google & GitHub Authentication✔ User Registration & Login✔ Profile/Dashboard Access✔ Secure & Mi...
Flask Blog CMS with Admin Dashboard — Python Source Code
A Flask-based blogging website with a built-in admin dashboard. Manage articles, images, categories, tags and featured p...
Laravel 12 + ReactJS Starter Kit: Add Multi-Language Support (Arabic, English, Spanish) with Blog CRUD
🚀 Installation & Setup Download & Extract Get the ZIP from kritimyantra.com and extract it. Includes preconfigu...
Comments
No comments yet. Be the first to comment.
Sign in to join the discussion.