Tutorial: Building an API with Laravel and Sanctum

Tutorial: Building an API with Laravel and Sanctum

Tutorial: Building an API with Laravel and Sanctum
13 min read

Laravel is one of the most popular and powerful PHP frameworks for web development, including APIs. Laravel Sanctum is a lightweight authentication package that allows us to secure APIs using tokens. In this comprehensive tutorial, we will cover everything from installation to authentication and CRUD API implementation using Laravel and Sanctum.


1. Setting Up a Laravel Project

1.1 Installing Laravel

Ensure you have Composer installed. If not, download it from Composer.

Run the following command to create a new Laravel project:

composer create-project laravel/laravel api-laravel-sanctum

Navigate to the project directory:

cd api-laravel-sanctum

Start the Laravel server:

php artisan serve

Your Laravel app should now be accessible at http://127.0.0.1:8000.

2. Installing and Configuring Sanctum

To manage API authentication, install Sanctum:

composer require laravel/sanctum

Publish Sanctum’s configuration file:

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

Run migrations to create the required database tables:

php artisan migrate

Modify the User model (app/Models/User.php) to include API token support:

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

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

Add Sanctum's middleware to app/Http/Kernel.php in the api section:

protected $middlewareAliases = [
    'auth:sanctum' => \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
];

Finally, enable the api guard in config/sanctum.php:

'guard' => ['web', 'api'],

3. Creating Authentication API (Register, Login, Logout)

3.1 Creating the Authentication Controller

Run the following command to generate an authentication controller:

php artisan make:controller AuthController

Open app/Http/Controllers/AuthController.php and add the following code:

namespace App\Http\Controllers;

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

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

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

    // LOGIN
    public function login(Request $request)
    {
        $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',
        ]);
    }

    // LOGOUT
    public function logout(Request $request)
    {
        $request->user()->tokens()->delete();

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

3.2 Adding API Routes

Edit routes/api.php and add these authentication routes:

use App\Http\Controllers\AuthController;

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

Route::middleware('auth:sanctum')->group(function () {
    Route::post('/logout', [AuthController::class, 'logout']);
});

4. Creating a CRUD API for Products

4.1 Creating the Model and Migration

Run the following command to generate a model and migration for products:

php artisan make:model Product -m

Modify the migration file in database/migrations/xxxx_xx_xx_xxxxxx_create_products_table.php:

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description');
        $table->decimal('price', 10, 2);
        $table->timestamps();
    });
}

Run the migration:

php artisan migrate

4.2 Creating the Product Controller

Generate a new controller:

php artisan make:controller ProductController

Open app/Http/Controllers/ProductController.php and add the following code:

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function index()
    {
        return response()->json(Product::all());
    }

    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'description' => 'required',
            'price' => 'required|numeric',
        ]);

        $product = Product::create($request->all());

        return response()->json($product, 201);
    }

    public function show(Product $product)
    {
        return response()->json($product);
    }

    public function update(Request $request, Product $product)
    {
        $product->update($request->all());

        return response()->json($product);
    }

    public function destroy(Product $product)
    {
        $product->delete();

        return response()->json(null, 204);
    }
}

4.3 Adding API Routes for Products

Modify routes/api.php to include product routes:

use App\Http\Controllers\ProductController;

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/products', [ProductController::class, 'index']);
    Route::post('/products', [ProductController::class, 'store']);
    Route::get('/products/{product}', [ProductController::class, 'show']);
    Route::put('/products/{product}', [ProductController::class, 'update']);
    Route::delete('/products/{product}', [ProductController::class, 'destroy']);
});

5. Testing the API

Use Postman or cURL to test the API. Remember to include the Bearer token in the Authorization header when accessing secured routes.


Conclusion

In this tutorial, we have:
• Installed Laravel and Sanctum
• Implemented authentication (register, login, logout)
• Created a CRUD API for products
• Secured the API using token-based authentication

Now, you have a fully functional API that can be used with mobile apps or frontend frameworks like Vue or React!

Recommended for you