Build With Abdallah logo Build With Abdallah Software · AI · Automation
Tutorial 7 min read Jun 07, 2026

Building a RESTful API with Laravel 13 and Sanctum for Authentication

In this tutorial, we will walk through the process of building a RESTful API using Laravel 13, a popular PHP framework. We will also implement authentication using Laravel Sanctum,

A
Abdallah Mohamed
Senior Full-Stack Engineer
Building a RESTful API with Laravel 13 and Sanctum for Authentication

Building a RESTful API with Laravel 13 and Sanctum for Authentication

In this tutorial, we will walk through the process of building a RESTful API using Laravel 13, a popular PHP framework. We will also implement authentication using Laravel Sanctum, a lightweight package for API token authentication. This combination is ideal for developers looking to create secure and scalable APIs for web and mobile applications.

Prerequisites

Before starting, ensure you have the following installed on your machine:

  • PHP >= 8.0
  • Composer
  • MySQL
  • Node.js & NPM

To install these prerequisites, you can use the following commands:

PHP and Composer

For Ubuntu:

sudo apt update
sudo apt install php8.0 php8.0-cli php8.0-fpm php8.0-mysql php8.0-xml php8.0-mbstring php8.0-zip php8.0-curl
sudo apt install composer

MySQL

For Ubuntu:

sudo apt update
sudo apt install mysql-server
sudo mysql_secure_installation

Node.js and NPM

For Ubuntu:

curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs

Verify the installations:

php -v
composer -v
mysql --version
node -v
npm -v

Project Structure

Once we set up our Laravel project, the directory structure will look like this:

my-laravel-api/
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
│   ├── api.php
│   └── web.php
├── storage/
├── tests/
└── vendor/

Step 1: Setting Up a New Laravel Project

First, create a new Laravel project using Composer:

composer create-project --prefer-dist laravel/laravel my-laravel-api

Navigate into the project directory:

cd my-laravel-api

Start the Laravel development server:

php artisan serve

Visit http://localhost:8000 in your browser to see the default Laravel welcome page.

Explanation

This step initializes a new Laravel project named my-laravel-api. The php artisan serve command starts a local development server, allowing you to view the default Laravel application.

Step 2: Configuring the Database

Edit the .env file in the root of your project to configure your database connection. Update the following lines with your database credentials:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_api
DB_USERNAME=root
DB_PASSWORD=your_password

Create the database using MySQL:

CREATE DATABASE laravel_api;

Run the following command to apply any pending migrations and set up the database schema:

php artisan migrate

Explanation

In this step, we connect our Laravel application to a MySQL database. The .env file stores environment-specific variables, including database credentials. Running php artisan migrate applies any migrations, setting up the necessary tables in the database.

Step 3: Installing and Setting Up Sanctum

Install Laravel Sanctum via Composer:

composer require laravel/sanctum

Publish the Sanctum configuration file:

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

Run the Sanctum migrations to create the necessary tables:

php artisan migrate

Next, add Sanctum's middleware to your api middleware group within your app/Http/Kernel.php file:

protected $middlewareGroups = [
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

Finally, in your config/auth.php, set the sanctum driver for the API authentication guard:

'guards' => [
    'api' => [
        'driver' => 'sanctum',
        'provider' => 'users',
        'hash' => false,
    ],
],

Explanation

In this step, we install and configure Laravel Sanctum for API token authentication. Sanctum provides a simple way to handle API authentication without the complexity of OAuth. We publish its configuration, run migrations, and update middleware and authentication settings to integrate Sanctum into our application.

Step 4: Creating API Endpoints

To create API endpoints, we will first define routes in routes/api.php and then create corresponding controllers.

4.1 Defining Routes

Open routes/api.php and add the following routes for user registration and login:

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

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

4.2 Creating the AuthController

Generate a new controller using Artisan:

php artisan make:controller AuthController

Open app/Http/Controllers/AuthController.php and implement the register and login methods:

namespace App\Http\Controllers;

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

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

        $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']);
    }

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

        if (!Auth::attempt($request->only('email', 'password'))) {
            return response()->json(['message' => 'Unauthorized'], 401);
        }

        $user = User::where('email', $request->email)->firstOrFail();
        $token = $user->createToken('auth_token')->plainTextToken;

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

Explanation

In this step, we define API routes and implement user registration and login functionality in the AuthController. The register method creates a new user and issues a token, while the login method authenticates an existing user and provides a token.

Step 5: Testing the API

To test the API, you can use tools like Postman or cURL.

5.1 Register a New User

Use the following cURL command to register a new user:

curl -X POST http://localhost:8000/api/register \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "email": "john@example.com", "password": "password"}'

5.2 Log in as a User

Use the following cURL command to log in:

curl -X POST http://localhost:8000/api/login \
-H "Content-Type: application/json" \
-d '{"email": "john@example.com", "password": "password"}'

Explanation

These commands demonstrate how to interact with the API endpoints for user registration and login. Successful requests return an access token.

Complete Working Example

Here are the key files for the complete working example:

routes/api.php

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

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

app/Http/Controllers/AuthController.php

namespace App\Http\Controllers;

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

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

        $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']);
    }

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

        if (!Auth::attempt($request->only('email', 'password'))) {
            return response()->json(['message' => 'Unauthorized'], 401);
        }

        $user = User::where('email', $request->email)->firstOrFail();
        $token = $user->createToken('auth_token')->plainTextToken;

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

Common Errors and Fixes

  1. Error: Class 'App\Models\User' not found

    • Fix: Ensure the User model exists in app/Models/. If not, run php artisan make:model User to generate it.
  2. Error: SQLSTATE[HY000] [1045] Access denied for user

    • Fix: Double-check your database credentials in the .env file. Ensure the username and password are correct.
  3. Error: Target class [AuthController] does not exist

    • Fix: Ensure the AuthController is correctly defined and the namespace matches the directory structure.

Conclusion

In this tutorial, we built a basic RESTful API using Laravel 13 and implemented authentication with Sanctum. You now have a foundational API setup that can be expanded with more features and endpoints.

Sources