Laravel

Using Laravel Sanctum for API Authentication

Administrator
By Administrator
Published Oct 07, 2025
5 min read
Using Laravel Sanctum for API Authentication

Introduction to Laravel Sanctum

Laravel Sanctum is a simple authentication library for SPAs (Single Page Applications), mobile applications, and basic token-based APIs. It allows you to issue and manage API tokens that can be used to authenticate requests to your application.

Unlike traditional session-based authentication, Sanctum uses API tokens that can be easily revoked and managed. This makes it perfect for modern applications that need to authenticate API calls from different clients.

Installing and Setting Up Laravel Sanctum

First, let's install Laravel Sanctum using Composer:

composer require laravel/sanctum

Next, publish the Sanctum configuration and migration files:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

php artisan migrate

Sanctum uses a single API tokens table to store all authentication tokens. The migration will create this table in your database.

Configuring Your User Model

To use Sanctum, you need to add the HasApiTokens trait to your User model:

// app/Models/User.php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

    // ... other model properties and methods
}

Creating Authentication Controllers

Let's create authentication controllers for login, registration, and user profile management:

php artisan make:controller API/AuthController --api
php artisan make:controller API/ProfileController --api

Now, let's implement the authentication logic:

// app/Http/Controllers/API/AuthController.php
namespace App\Http\Controllers\API;

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

class AuthController extends Controller
{
    /**
     * User registration
     */
    public function register(Request $request): JsonResponse
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
            'password' => 'required|string|min:8|confirmed',
        ]);

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

        // Create personal access token for the user
        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'success' => true,
            'message' => 'User registered successfully',
            'user' => $user,
            'token' => $token,
            'token_type' => 'Bearer',
        ], 201);
    }

    /**
     * User login
     */
    public function login(Request $request): JsonResponse
    {
        $credentials = $request->validate([
            'email' => 'required|email',
            'password' => 'required|string',
        ]);

        if (!Auth::attempt($credentials)) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid credentials',
            ], 401);
        }

        $user = Auth::user();
        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'success' => true,
            'message' => 'Login successful',
            'user' => $user,
            'token' => $token,
            'token_type' => 'Bearer',
        ]);
    }

    /**
     * User logout
     */
    public function logout(Request $request): JsonResponse
    {
        $request->user()->currentAccessToken()->delete();

        return response()->json([
            'success' => true,
            'message' => 'Successfully logged out',
        ]);
    }
}

Protecting API Routes with Authentication

Laravel Sanctum provides convenient middleware for protecting your API routes. Update your API routes file:

// routes/api.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\ProfileController;

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

// Protected routes (require authentication)
Route::middleware('auth:sanctum')->group(function () {
    Route::get('profile', [ProfileController::class, 'show']);
    Route::put('profile', [ProfileController::class, 'update']);
    Route::post('logout', [AuthController::class, 'logout']);

    // Token management
    Route::get('tokens', [ProfileController::class, 'tokens']);
    Route::delete('tokens/{token}', [ProfileController::class, 'revokeToken']);
});

// Route for testing authentication
Route::middleware('auth:sanctum')->get('user', function (Request $request) {
    return $request->user();
});

Implementing Profile Management

Let's implement the profile controller to manage user profiles and API tokens:

// app/Http/Controllers/API/ProfileController.php
namespace App\Http\Controllers\API;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class ProfileController extends Controller
{
    /**
     * Get user profile
     */
    public function show(Request $request): JsonResponse
    {
        return response()->json([
            'success' => true,
            'user' => $request->user()
        ]);
    }

    /**
     * Update user profile
     */
    public function update(Request $request): JsonResponse
    {
        $user = $request->user();

        $validated = $request->validate([
            'name' => 'sometimes|required|string|max:255',
            'email' => 'sometimes|required|email|unique:users,email,'.$user->id,
            'phone' => 'nullable|string|max:20',
        ]);

        $user->update($validated);

        return response()->json([
            'success' => true,
            'message' => 'Profile updated successfully',
            'user' => $user
        ]);
    }

    /**
     * Get user's API tokens
     */
    public function tokens(Request $request): JsonResponse
    {
        return response()->json([
            'success' => true,
            'tokens' => $request->user()->tokens
        ]);
    }

    /**
     * Revoke a specific API token
     */
    public function revokeToken(Request $request, $tokenId): JsonResponse
    {
        $token = $request->user()->tokens()->where('id', $tokenId)->first();

        if (!$token) {
            return response()->json([
                'success' => false,
                'message' => 'Token not found'
            ], 404);
        }

        $token->delete();

        return response()->json([
            'success' => true,
            'message' => 'Token revoked successfully'
        ]);
    }
}

Creating Tokens with Different Abilities

Sanctum allows you to create tokens with specific abilities or permissions:

// Creating a token with specific abilities
$token = $user->createToken('My App', ['read:posts', 'write:posts']);

// Creating a token with no abilities (restricted)
$token = $user->createToken('Restricted Access', []);

// Creating a regular token (all abilities)
$token = $user->createToken('Full Access');

Using the Authentication System in Applications

For JavaScript Applications:

// Login
const login = async (email, password) => {
    const response = await fetch('/api/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email, password }),
    });

    const data = await response.json();

    if (data.success) {
        localStorage.setItem('auth_token', data.token);
        localStorage.setItem('user', JSON.stringify(data.user));
    }

    return data;
};

// Protected API call
const getProfile = async () => {
    const token = localStorage.getItem('auth_token');

    const response = await fetch('/api/profile', {
        headers: {
            'Authorization': `Bearer ${token}`,
            'Accept': 'application/json',
        },
    });

    return response.json();
};

For Mobile Applications (cURL example):

// Login
curl -X POST http://your-app.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"password"}'

# Protected API call
curl -X GET http://your-app.com/api/profile \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Token Management and Security Best Practices

  1. Token Expiration: Implement token expiration and refresh mechanisms
  2. Multiple Devices: Allow users to manage tokens from multiple devices
  3. Token Abilities: Use token abilities for fine-grained permissions
  4. HTTPS Only: Always use HTTPS for API endpoints
  5. Token Storage: Store tokens securely in client applications
  6. Regular Cleanup: Remove unused tokens periodically

Advanced Authentication Features

Personal Access Tokens with Custom Abilities:

class TokenController extends Controller
{
    public function createCustomToken(Request $request): JsonResponse
    {
        $abilities = $request->input('abilities', []);

        if (!is_array($abilities)) {
            return response()->json([
                'success' => false,
                'message' => 'Abilities must be an array'
            ], 422);
        }

        $token = $request->user()->tokens()->create([
            'name' => $request->input('name', 'Custom Token'),
            'abilities' => $abilities,
        ]);

        return response()->json([
            'success' => true,
            'token' => $token->id,
            'plainTextToken' => $token->plainTextToken,
            'abilities' => $token->abilities,
        ]);
    }
}

Conclusion

Laravel Sanctum provides a simple yet powerful solution for API authentication in Laravel applications. By following this tutorial, you've learned how to set up Sanctum, create authentication endpoints, protect routes, and manage API tokens.

Remember to implement proper security practices, use HTTPS for all API requests, and manage tokens responsibly. Sanctum is particularly well-suited for SPAs, mobile apps, and simple API authentication scenarios.

Happy coding with Laravel Sanctum!

Related Articles

How to Send Emails in Laravel Using Mailables

How to Send Emails in Laravel Using Mailables

Oct 07, 2025

Introduction to Laravel Mailables Sending emails in Laravel has never been easier thanks to Maila...

Laravel Queues and Jobs: Complete Beginner's Guide

Laravel Queues and Jobs: Complete Beginner's Guide

Oct 07, 2025

What Are Laravel Queues? Laravel Queues allow you to defer processing of time-consuming tasks. In...

How to Handle File Uploads in Laravel

How to Handle File Uploads in Laravel

Oct 07, 2025

Introduction to File Uploads in Laravel File uploads are a fundamental feature in most web applic...

Building RESTful APIs with Laravel

Building RESTful APIs with Laravel

Oct 07, 2025

Introduction to RESTful APIs in Laravel Building APIs is one of the most common tasks for modern...