Laravel 12 + Vue.js 3 Authentication (2026): Full Beginner-Friendly Guide with Real-World Examples

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:

  1. SPA authentication (cookies + sessions) ✅ we’ll use this
  2. 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:

  • /user only works when logged in
  • /logout only 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.

Discussion

Comments

No comments yet. Be the first to comment.

Browse the project library

Projects to explore next

Source-code projects from the KritiMyantra catalogue. Check each project's details before buying.

All projects