Skip to content

Building a Robust API with Laravel 11 and Sanctum: A Step-by-Step Guide

Laravel, a PHP framework renowned for its elegance and developer experience, has become a cornerstone for building web applications. In today’s digital landscape, RESTful APIs are the backbone of many applications, powering interactions between different systems. This guide will delve into creating a secure and efficient API using Laravel 11 and Sanctum, a lightweight authentication package ideal for token-based authentication.

Token-based authentication offers several advantages over traditional session-based methods. It’s stateless, scalable, and provides a more secure approach to protecting your API. Sanctum simplifies this process by providing a streamlined way to issue and manage API tokens for your users.

In the following sections, we’ll explore how to set up a Laravel 11 project, integrate Sanctum, create user models, build the authentication controller, define API routes, and implement token-based authentication. We’ll also discuss essential security considerations and best practices to ensure the robustness of your API.

Prerequisites:

  • Basic understanding of PHP, Laravel concepts, and RESTful APIs
  • A local development environment with Laravel 11 installed
  • A database (e.g., MySQL) configured with Laravel


Creating a New Laravel Project

To begin, let’s create a fresh Laravel 11 project.
Open your terminal and run the following command:
composer create-project laravel/laravel my-api

Enable API routing using the install:api Artisan command and define the route in your routes/api.php file.

The install:api command installs Laravel Sanctum, which provides a robust, yet simple API token authentication guard which can be used to authenticate third-party API consumers, SPAs, or mobile applications.
In addition, the install:api command creates the routes/api.php file.
Read more https://laravel.com/docs/11.x/routing.


Modifying the Existing User Model

Open the app/Models/User.php file and add the necessary fields to the $fillable array. These fields will be mass assignable:

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; 

class User extends Authenticatable {
     use HasApiTokens, HasFactory, Notifiable;
    /**
     * The attributes that are mass assignable. 
     *
     */
protected $fillable = [
        'name',
        'email',
        'password',   

  // Add other fields as needed, e.g., 'first_name', 'last_name', 'phone'
    ];

If you need to add new columns to the users table, you’ll need to create a migration. You can use the following command:
php artisan make:migration add_new_fields_to_users_table
Then, open the migration file and add the necessary columns to the up method. If you didn’t add any method there is no need to create the migration.


Creating the AuthController

Before defining the routes, we need to create an AuthController.
The generated AuthController provides methods for registration, login and logout.
You can customize these methods to fit your specific needs.
The following command will create an AuthController in the app/Http/Controllers/Api directory:
php artisan make:controller Api/AuthController


Creating AuthController Methods

Let’s start by defining the basic structure of our AuthController controller. Open the app/Http/Controllers/AuthController.php file and add the following code:

<?php

namespace App\Http\Controllers;

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

class AuthController extends Controller
{
    public function register(Request $request)
    {
        // Validation  and user creation logic
    }

    public function login(Request $request)
    {
        // Login logic
    }

    public function logout(Request $request)
    {
        // Logout logic
    }
}





Creating API Routes

Laravel provides a dedicated file for API routes: routes/api.php.

To define routes for registration, login, and logout, open the routes/api.php file and add the following:

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

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', 
[AuthController::class, 'logout'])->middleware('auth:sanctum');

If you call the comand php artisan route:list, you should see the api just defined.


Register Method

Let’s implement the register method:

public function register(Request $request) {
        // Validation  and user creation logic
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|unique:users',
            'password' => 'required|string|min:8|confirmed',
        ]);

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

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

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

This code validates the incoming request data, creates a new user, generates a token using Sanctum, and returns both the token and user information.



Login Method

Next, let’s implement the login method:

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

        $user = User::where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['The provided credentials are incorrect.'],
            ]);
        }

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

        return response()->json(['access_token' => $token, 
'token_type' => 'Bearer', 
'user' => $user], 200);

    }

This code validates the credentials, checks if the user exists and the password matches, and returns a token if successful.


Logout Method

Finally, let’s implement the logout method:

    public function logout(Request $request) {
        // Logout logic
        $request->user()->currentAccessToken()->delete();

        return response()->json([
'message' => 'Logged out successfully'], 200);

    }

This code deletes the current access token and returns a success message.

Note: This is a basic implementation. You might want to add more features like error handling, password reset, email verification, and other security measures.


Testing Your API Routes

A straightforward way to test your API routes is by using a tool like Postman:

  1. Start the Laravel development server:
    php artisan serve
  2. Open Postman: Create requests for each of your API endpoints (register, login, logout).
  3. Set request headers: For authentication, you’ll need to include the Authorization header with the Bearer token in subsequent requests.
  4. Send requests: Send the appropriate HTTP method (POST, GET, etc.) with the required data in the request body.



Testing user registration

  • Method: POST
  • URL: http://127.0.0.1:8000/api/register
  • Headers: Content-Type: application/json
  • Body:
    • Raw
    • JSON
      {
      "name": "John Doe",
      "email": "johndoe@example.com",
      "password": "password123",
      "password_confirmation": "password123"
      }


Testing user authentication

After correctly registered, you can send a POST request to the login endpoint with email and password.

  • Method: POST
  • URL: http://127.0.0.1:8000/api/login
  • Use the token: Include the Authorization header with the Bearer token in subsequent requests
  • Enter the URL: In the address bar, enter the URL of your login endpoint. For example, if your API is running on http://127.0.0.1:8000, and your login endpoint is at /api/login, the URL would be http://127.0.0.1:8000/api/login.
  • Headers: Content-Type: application/json
  • Body:
    • Raw
    • JSON
      {
      "email": "your_email@example.com",
      "password": "your_password"
      }

If the login is successful, you should receive a response with a JSON object containing the access token that can be used to authenticate subsequent requests.


Testing the logout endpoint

  • Method: POST
  • Headers: Authorization: Bearer <your_access_token>.

If the logout is successful, you should receive a response indicating that the user has been logged out.



Conclusion

Building a robust authentication system is a crucial aspect of any web application.
Laravel 11, in conjunction with Sanctum, provides a powerful and efficient way to implement registration, login, and logout functionalities for your API.

By following the steps outlined in this guide, you’ve learned how to:

  • Set up a Laravel 11 project.
  • Install and configure Sanctum.
  • Create a User model and its migration.
  • Build an AuthController to handle registration, login, and logout.
  • Define API routes for authentication.
  • Test your API using Postman or other tools.


Key takeaways:

  • Sanctum simplifies token-based authentication for Laravel applications.
  • Proper user authentication is essential for security and user experience.
  • Understanding the concepts of registration, login, and logout is fundamental for API development.


Further Exploration:

Building upon the foundation of registration, login, and logout, you can delve into more advanced features to enrich your Laravel API:

  • Additional features: explore features like password reset (to allow users to recover their accounts), email verification, and two-factor authentication. Two-Factor Authentication (2FA) adds an extra layer of security by requiring users to provide a second form of authentication, such as a code sent to their phone.
  • Security best practices: implement robust security measures to protect your API from vulnerabilities. Rate limiting, i.e. prevent brute-force attacks and abuse by limiting the number of requests a user can make within a given time period. CORS Configuration, if your API is consumed by a frontend application on a different domain, configure CORS to allow cross-origin requests.
  • API Documentation: Generate API documentation using tools like Swagger or OpenAPI to make your API easier to understand and use.
  • Testing: Write comprehensive unit and integration tests to ensure the quality and reliability of your API.
  • Deployment: Explore deployment options like Laravel Forge, DigitalOcean, or AWS to deploy your API to a production environment.

By exploring these areas, you can create a more robust, secure, and user-friendly API that meets the needs of your application. Armed with this knowledge, you’re ready to explore the vast possibilities of API development with Laravel. Happy coding!