Laravel Sanctum is a package that provides a simple way to secure your REST API. For instance, if you want your users to build services on top of your application, Laravel Sanctum offers a straightforward approach.

Laravel 11 Sanctum API - Laravel 11 REST API Authentication using Sanctum Tutorial

Table Of Content

1 Prerequisites

1.) PHP version of >= 8.2
2.) Composer
3.) Mysql

2 Introduction

In this tutorial, we will learn about Laravel Sanctum for API authentication by developing a complete application with REST API Authentication using Sanctum. This is a step-by-step guide to creating a Laravel 11 Sanctum REST API Authentication Example.

3 Create / Install a Laravel Project

3.1 Install Laravel Project

Ensure you have Composer installed. Use the following command to install a new Laravel Project:

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

Then, navigate to your project directory:

cd laravel11-sanctum-api

3.2 Configure MySql Database

The user's records will be stored in the database. Access the .env file and define the database credentials:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sanctum
DB_USERNAME=root
DB_PASSWORD=

4 Install Laravel Sanctum

In Laravel 11, install Sanctum using the following command:
    
        php artisan install:api
   

5 Add HasApiTokens in User Model

In the User model, include the HasApiTokens class of Sanctum:
    
<?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 HasFactory, Notifiable,HasApiTokens;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}


   

6 Create Controller - AuthController

Create a controller for handling API functionality:

php artisan make:controller Api/AuthController

In AuthController.php, define three functions: register, login, and logout.

<?php
namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Validator;
use Illuminate\Http\JsonResponse;

class AuthController extends Controller
{
    public function register(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email|unique:users,email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);
   
        if($validator->fails()){
           return response()->json([
            'status' => 'failed',
            'message' => 'Validation Error!',
            'data' => $validator->errors(),
        ], 403);
        }
   
        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] =  $user->createToken('auth_token')->plainTextToken;
        $success['name'] =  $user->name;
        $message='User is created successfully.';

    $response = [
        'success' => true,
        'data'    => $success,
        'message' => $message,
    ];
    return response()->json($response, 200);
    }
    public function login(Request $request): JsonResponse
    {

        $validate = Validator::make($request->all(), [
            'email' => 'required|string|email',
            'password' => 'required|string'
        ]);

        if($validate->fails()){
            return response()->json([
                'status' => 'failed',
                'message' => 'Validation Error!',
                'data' => $validate->errors(),
            ], 403);  
        }

        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ 
            $user = Auth::user(); 
            $success['token_type'] ='Bearer';
            $success['token'] =  $user->createToken('auth_token')->plainTextToken; 
            $success['name'] =  $user->name;
            $message='User is logged in successfully';
            $response = [
                'success' => true,
                'data'    => $success,
                'message' => $message,
                 ];
            return response()->json($response, 200);

        } 
        else{ 
            $response = [
                'success' => false,
                'message' => 'Invalid credentials',
            ];
          return response()->json($response, 401);
        } 
    }
    public function logout(): JsonResponse
    {
        Auth::user()->tokens()->delete();
        return response()->json([
        'message' => 'Logout successfull'
         ]);
    }
}
?>

7 Add Blog Table and Model

Create a migration for the blogs table:

    php artisan make:migration create_blogs_table

After this command, you will find one file in the following path database/migrations, and you have to put the below code in your migration file to create the blogs table.
    
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('blogs', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('description');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('blogs');
    }
};

After creating the migration, run:

php artisan migrate

Next, create a Blog model at app/Models/Blog.php:
    
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    use HasFactory;
    protected $fillable = [
        'name',
        'description'
    ];
}



8 Define API Endpoints in routes/api.php

Define your API routes in api.php:

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


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

// Public routes of Blog
Route::controller(BlogController::class)->group(function() {
    Route::get('/blogs', 'index');
    Route::get('/blogs/{id}', 'show');
    Route::get('/blogs/search/{name}', 'search');
});


Route::middleware('auth:sanctum')->group(function () {
    Route::post('/logout', [AuthController::class, 'logout']);
    Route::controller(BlogController::class)->group(function() {
        Route::post('/blogs', 'store');
        Route::post('/blogs/{id}', 'update');
        Route::delete('/blogs/{id}', 'destroy');
    });
});
Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');


9 Folder Structure

The folder structure will look like this:

10 Run Laravel Server to Test the App

Use the following command to run the Laravel server:

php artisan serve

11 Conclusion

You have successfully implemented Laravel Sanctum REST API Authentication using Sanctum in Laravel 11.

Tags