Introduction
In modern web development, APIs are the backbone of communication between clients such as web browsers, mobile applications, and backend servers. Because APIs often expose sensitive data and critical functionality, implementing secure authentication and authorization is essential.
One widely adopted solution for API authentication is JSON Web Token (JWT). JWT provides a simple, secure, and stateless way to authenticate users by transmitting signed tokens between the client and the server. This approach is especially popular in Single Page Applications (SPAs) and mobile apps, where traditional session-based authentication is not ideal.
In this tutorial, you will learn how to build a Laravel 12 + Vue 3 SPA authentication system using JWT, following best practices and a clean project structure suitable for real-world applications.
What is JWT?
JSON Web Token (JWT) is an open standard (RFC 7519) used to securely transmit information as a JSON object between two parties. A JWT is:
-
Self-contained – it contains user identity and claims
-
Compact – easy to send in HTTP headers
-
Digitally signed – ensures data integrity
-
Stateless – no server-side session storage required
JWTs are commonly used to authenticate users in web applications, mobile apps, and public APIs, where each request includes a token in the Authorization: Bearer <token> header. This allows the server to verify the user's identity without maintaining session data.
Prerequisites
Before starting this tutorial, make sure you have the following installed:
-
PHP 8.1 or higher
-
Composer
-
Node.js & npm
-
MySQL
-
Basic knowledge of Laravel and Vue 3
Step 1: Create Laravel Project
Step 2: Install JWT Package
Install the php-open-source-saver/jwt-auth package:
Publish the package configuration:
Generate the JWT secret key (add to .env):
Open .env and set:
(Change DB settings if needed)
Step 3: Run the migration command
Step 4: Update User Model
Edit app/Models/User.php to implement JWTSubject:
Step 5: Configure Authentication Guard
Open config/auth.php and update the api guard to use jwt driver:
Step 6: Create Auth Controller
Generate the controller:
Edit app/Http/Controllers/API/AuthController.php:
Step 7: Create Form Request Validations
Edit app/Http/Requests/RegisterRequest.php:
Edit app/Http/Requests/LoginRequest.php:
Step 8: Create User API Resource
Edit app/Http/Resources/UserResource.php:
Step 9: Define API Routes
Edit routes/api.php:
Step 10: Create Vue Project Directories & Files
Step 11: Install Vue 3 Dependencies
Step 12: Configure Vite
Edit vite.config.js:
Step 13: Vue Router Setup
Edit resources/js/router/index.js:
Step 14: Pinia Store Setup
Edit resources/js/stores/auth.js:
Step 15: API Service Helper
Edit resources/js/services/api.js:
Step 16: Vue Entry Point
Edit resources/js/app.js:
Step 17: Main Vue Component
Edit resources/js/App.vue:
Step 18: Vue Components (Login, Register, Dashboard)
Login.vue
Register.vue
Dashboard.vue
Step 19: Blade View to Load Vue SPA
Edit routes/web.php:
Create resources/views/welcome.blade.php:
Step 20: Run Your Project
Open two terminals:
Start Laravel backend:
Start frontend dev server:
Step 21: Visit Your App
Open browser:
You now have a secure SPA with:

