Laravel 12 API Authentication with Passport & Vue.js Integration (Beginner-Friendly Guide)

Author

Kritim Yantra

Jun 08, 2025

Laravel 12 API Authentication with Passport & Vue.js Integration (Beginner-Friendly Guide)

In this blog, we'll walk through setting up Laravel 12 with Passport API Authentication and integrating it with a Vue.js frontend. This guide is beginner-friendly, so even if you're new to Laravel APIs or Vue.js, you'll be able to follow along easily.


Prerequisites

Before we begin, ensure you have:

  • PHP (>= 8.1) & Composer installed
  • Node.js & npm (for Vue.js)
  • Laravel 12 installed (composer create-project laravel/laravel laravel-passport-vue)
  • Basic knowledge of Laravel & Vue.js

Step 1: Install Laravel 12 & Set Up API Routes

Laravel 12 introduces a new way to set up APIs using the api:install command.

1.1 Install Laravel & Configure Database

Run:

composer create-project laravel/laravel laravel-passport-vue
cd laravel-passport-vue

Update your .env file with database credentials.

1.2 Run api:install (Installs Sanctum by Default)

Laravel 12 simplifies API setup:

php artisan api:install

This will:

  • Create routes/api.php
  • Install Laravel Sanctum (default for APIs)
  • Publish Sanctum’s config & migrations

But since we want Passport (for OAuth2), we'll modify this.


Step 2: Install & Configure Laravel Passport

Since we need Passport instead of Sanctum, we'll install it manually.

2.1 Install Passport

Run:

composer require laravel/passport
php artisan migrate
php artisan passport:install

This generates OAuth2 encryption keys and creates oauth_clients in the database.

2.2 Configure Passport in AuthServiceProvider

Open app/Providers/AuthServiceProvider.php and update:

use Laravel\Passport\Passport;

public function boot(): void
{
    Passport::tokensExpireIn(now()->addDays(15));
    Passport::refreshTokensExpireIn(now()->addDays(30));
    Passport::personalAccessTokensExpireIn(now()->addMonths(6));
}

2.3 Update config/auth.php

Set the API guard to use Passport:

'guards' => [
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

Step 3: Create API Authentication Routes

Open routes/api.php and add:

use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);

// Protected routes (require auth)
Route::middleware('auth:api')->group(function () {
    Route::get('/user', [AuthController::class, 'user']);
    Route::post('/logout', [AuthController::class, 'logout']);
});

3.1 Create AuthController

Run:

php artisan make:controller AuthController

Update app/Http/Controllers/AuthController.php:

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;

public function register(Request $request)
{
    $request->validate([
        'name' => 'required|string',
        'email' => 'required|email|unique:users',
        'password' => 'required|min:8|confirmed',
    ]);

    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => Hash::make($request->password),
    ]);

    $token = $user->createToken('authToken')->accessToken;

    return response()->json(['token' => $token], 201);
}

public function login(Request $request)
{
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    if (!Auth::attempt($request->only('email', 'password'))) {
        return response()->json(['error' => 'Invalid credentials'], 401);
    }

    $user = Auth::user();
    $token = $user->createToken('authToken')->accessToken;

    return response()->json(['token' => $token]);
}

public function user(Request $request)
{
    return response()->json($request->user());
}

public function logout(Request $request)
{
    $request->user()->token()->revoke();
    return response()->json(['message' => 'Logged out']);
}

Step 4: Set Up Vue.js Frontend

We’ll use Vue 3 with axios for API calls.

4.1 Install Vue.js & Axios

Run:

npm install vue@next axios
npm install --save-dev @vitejs/plugin-vue

4.2 Configure vite.config.js

Update:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel(['resources/js/app.js']),
        vue(),
    ],
});

4.3 Create Vue Components

Create resources/js/App.vue:

<template>
    <div>
        <h1>Laravel Passport + Vue.js Auth</h1>
        <div v-if="!user">
            <input v-model="form.email" placeholder="Email" />
            <input v-model="form.password" placeholder="Password" type="password" />
            <button @click="login">Login</button>
            <button @click="register">Register</button>
        </div>
        <div v-else>
            <p>Welcome, {{ user.name }}!</p>
            <button @click="logout">Logout</button>
        </div>
    </div>
</template>

<script>
import axios from 'axios';

export default {
    data() {
        return {
            form: {
                email: '',
                password: '',
            },
            user: null,
        };
    },
    mounted() {
        this.getUser();
    },
    methods: {
        async login() {
            try {
                const res = await axios.post('/api/login', this.form);
                localStorage.setItem('token', res.data.token);
                await this.getUser();
            } catch (err) {
                alert(err.response.data.error || 'Login failed');
            }
        },
        async register() {
            try {
                const res = await axios.post('/api/register', {
                    ...this.form,
                    password_confirmation: this.form.password,
                });
                localStorage.setItem('token', res.data.token);
                await this.getUser();
            } catch (err) {
                alert(err.response.data.message || 'Registration failed');
            }
        },
        async getUser() {
            try {
                const token = localStorage.getItem('token');
                if (!token) return;
                
                axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
                const res = await axios.get('/api/user');
                this.user = res.data;
            } catch (err) {
                localStorage.removeItem('token');
            }
        },
        async logout() {
            try {
                await axios.post('/api/logout');
                localStorage.removeItem('token');
                this.user = null;
            } catch (err) {
                alert('Logout failed');
            }
        },
    },
};
</script>

4.4 Update resources/js/app.js

import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');

4.5 Update Blade File (welcome.blade.php)

Replace with:

<!DOCTYPE html>
<html>
<head>
    <title>Laravel + Vue + Passport</title>
    @vite(['resources/js/app.js'])
</head>
<body>
    <div id="app"></div>
</body>
</html>

Step 5: Test the Application

  1. Run Laravel:
    php artisan serve
    
  2. Run Vite for frontend:
    npm run dev
    
  3. Visit http://localhost:8000 and test:
    • Registration
    • Login
    • Logout
    • Protected user data fetch

Conclusion

You’ve successfully set up:
Laravel 12 API with Passport Auth
Vue.js 3 Frontend Integration
Token-based Authentication

This setup is perfect for SPAs (Single Page Applications) and mobile apps.

Hope this helps! 🚀 Let me know if you have any questions.

Happy Coding! 😊

LIVE MENTORSHIP ONLY 5 SPOTS

Laravel Mastery
Coaching Class Program

KritiMyantra

Transform from beginner to Laravel expert with our personalized Coaching Class starting June 19, 2025. Limited enrollment ensures focused attention.

Daily Sessions

1-hour personalized coaching

Real Projects

Build portfolio applications

Best Practices

Industry-standard techniques

Career Support

Interview prep & job guidance

Total Investment
$200
Duration
30 hours
1h/day

Enrollment Closes In

Days
Hours
Minutes
Seconds
Spots Available 5 of 10 remaining
Next cohort starts:
June 19, 2025

Join the Program

Complete your application to secure your spot

Application Submitted!

Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.

What happens next?

  • Confirmation email with program details
  • WhatsApp message from our team
  • Onboarding call to discuss your goals

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts