Secure Authentication in Single-Page Applications: A Step-by-Step Guide
The Challenge of Authentication in SPAs
Single-page applications (SPAs) present a unique challenge when it comes to authentication. Developers often rely on local storage or session storage to save user tokens, but these methods are vulnerable to XSS attacks and lack the security features needed to protect sensitive user data.
Introducing Laravel Sanctum
Laravel Sanctum is a package designed for authenticating single-page applications, mobile apps, and token-based APIs. It provides a robust and secure way to generate API tokens for users and authenticate them using a Laravel session.
Building a Secure Nuxt.js App with Laravel Sanctum
In this tutorial, we’ll build a simple Nuxt.js app with authentication powered by a Laravel API. We’ll cover the following topics in detail:
- Creating a Laravel app
- Setting up Laravel Sanctum
- Building a Laravel API
- Creating a Nuxt.js application
- Implementing cookie-based authentication
- Restricting access to authenticated users
Creating a Laravel App
To get started, make sure you have the latest PHP LTS version (v8.1.5 or higher) and a globally installed PHP Composer CLI (v2.3.5 or higher). Then, create a new Laravel application using the Laravel Installer:
composer create-project --prefer-dist laravel/laravel project-name
Setting up Laravel Sanctum
Next, install Laravel Sanctum and configure the Laravel app for authentication:
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Configure the sanctum.php
file to set up the database and authentication settings.
Building a Laravel API
With Sanctum set up, let’s build a simple Laravel API that includes endpoints for authenticating users, fetching user details, and logging out:
// routes/api.php
Route::post('/login', 'AuthController@login');
Route::get('/user', 'AuthController@user');
Route::post('/logout', 'AuthController@logout');
// app/Http/Controllers/AuthController.php
public function login(Request $request) {
// authenticate user and generate API token
}
public function user(Request $request) {
// fetch user details
}
public function logout(Request $request) {
// logout user and revoke API token
}
Seed the database with a dummy user for testing purposes:
// database/seeds/UserSeeder.php
factory(User::class)->create([
'name' => 'John Doe',
'email' => '[email protected]',
'password' => bcrypt('password'),
]);
Creating a Nuxt.js Application
Now, let’s move on to the SPA itself. Create a new Nuxt.js application using the command-line interface:
npx create-nuxt-app my-nuxt-app
cd my-nuxt-app
npm install @buefy/vue-ui
Implementing Cookie-Based Authentication
To implement authentication, we’ll use the nuxt/auth
module and configure it to work with Laravel Sanctum:
// nuxt.config.js
export default {
modules: ['@nuxtjs/auth'],
auth: {
strategies: {
sanctum: {
scheme: 'cookie',
token: {
property: 'token',
global: true,
required: true,
type: 'Bearer'
},
endpoints: {
login: { url: '/api/login', method: 'post' },
user: { url: '/api/user', method: 'get' },
logout: { url: '/api/logout', method: 'post' }
}
}
}
}
}
Create a login page using Buefy Vue UI components and add functionality for logging in and fetching user details:
Login
Restricting Access to Authenticated Users
Finally, let’s restrict access to the homepage to only authenticated users. We’ll use the auth
middleware provided by the nuxt-auth
module to redirect unauthenticated users to the login page:
// pages/index.vue
export default {
middleware: ['auth']
}