In today’s web development landscape, secure and efficient session authentication is crucial. Laravel 11, combined with Vue 3, offers a powerful solution for implementing cookies-based session authentication through Laravel Sanctum. This guide provides a comprehensive, step-by-step approach to integrating these technologies, ensuring your application is both secure and user-friendly.
Introduction to Laravel Sanctum
Laravel Sanctum provides a simple way to authenticate Single Page Applications (SPAs) using cookies-based session authentication. Sanctum is versatile and lightweight, making it ideal for modern web applications. It allows each user of your application to generate multiple API tokens for their account, providing the ability to authenticate with third-party services.
Setting Up Laravel 11
First, ensure you have Laravel 11 installed. If not, you can install it using Composer:
composer create-project --prefer-dist laravel/laravel project-name "11.*"
Navigate to your project directory:
cd project-name
Next, install Laravel Sanctum:
composer require laravel/sanctum
Publish the Sanctum configuration:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Run the migrations to create the necessary tables:
php artisan migrate
Configuring Sanctum
To use Sanctum for cookies-based session authentication, you need to configure it in your sanctum.php
configuration file. Ensure the following settings are enabled:
'session' => true,
In the api.php
or web.php
middleware group, add Sanctum’s middleware:
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
protected $middlewareGroups = [
'web' => [
// other middleware
EnsureFrontendRequestsAreStateful::class,
// other middleware
],
'api' => [
// other middleware
EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Setting Up Authentication Routes
Create authentication routes in your routes/web.php
file. These routes will handle login, logout, and fetch the authenticated user:
use App\Http\Controllers\AuthController;
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout']);
Route::get('/user', [AuthController::class, 'user']);
Building the Authentication Controller
In the app/Http/Controllers
directory, create the AuthController
:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return response()->json(Auth::user(), 200);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return response()->json(['message' => 'Logged out successfully'], 200);
}
public function user(Request $request)
{
return response()->json(Auth::user(), 200);
}
}
Setting Up Vue 3
Install Vue 3 in your Laravel project. If you haven’t already installed it, you can set it up using Laravel Mix. First, install the necessary packages:
npm install vue@next vue-loader@next
Update your webpack.mix.js
file to handle Vue components:
const mix = require('laravel-mix');
const { VueLoaderPlugin } = require('vue-loader');
mix.js('resources/js/app.js', 'public/js')
.vue()
.sass('resources/sass/app.scss', 'public/css');
mix.webpackConfig({
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
new VueLoaderPlugin()
]
});
Creating Vue Components for Authentication
In the resources/js
directory, create a new folder named components
and add the following Vue components:
LoginComponent.vue
<template>
<div>
<form @submit.prevent="login">
<input v-model="email" type="email" placeholder="Email" required />
<input v-model="password" type="password" placeholder="Password" required />
<button type="submit">Login</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
email: '',
password: ''
};
},
methods: {
async login() {
try {
const response = await axios.post('/login', {
email: this.email,
password: this.password
});
console.log('Login successful', response.data);
} catch (error) {
console.error('Login failed', error.response.data);
}
}
}
};
</script>
LogoutComponent.vue
<template>
<div>
<button @click="logout">Logout</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
methods: {
async logout() {
try {
const response = await axios.post('/logout');
console.log('Logout successful', response.data);
} catch (error) {
console.error('Logout failed', error.response.data);
}
}
}
};
</script>
UserComponent.vue
<template>
<div>
<p v-if="user">Welcome, {{ user.name }}</p>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
user: null
};
},
async created() {
try {
const response = await axios.get('/user');
this.user = response.data;
} catch (error) {
console.error('Failed to fetch user', error.response.data);
}
}
};
</script>
Integrating Vue Components into Your Application
Modify your resources/js/app.js
to register these components:
import { createApp } from 'vue';
import LoginComponent from './components/LoginComponent.vue';
import LogoutComponent from './components/LogoutComponent.vue';
import UserComponent from './components/UserComponent.vue';
const app = createApp({});
app.component('login-component', LoginComponent);
app.component('logout-component', LogoutComponent);
app.component('user-component', UserComponent);
app.mount('#app');
Ensure you have a corresponding HTML element with the id app
in your resources/views/welcome.blade.php
or any other Blade view file where you want to display these components:
<div id="app">
<login-component></login-component>
<user-component></user-component>
<logout-component></logout-component>
</div>
<script src="{{ mix('js/app.js') }}"></script>
Testing the Implementation
Run your Laravel server:
php artisan serve
And your development server for Vue:
npm run dev
Visit http://localhost:8000
to see your application in action. You should be able to login, logout, and fetch the authenticated user’s details seamlessly.
Conclusion
Implementing cookies-based session authentication using Laravel Sanctum and Vue 3 ensures a secure and efficient authentication process for your SPA. By following this guide, you have set up a robust authentication system that leverages the strengths of both Laravel and Vue.