Tutorial: Building an API with Laravel and Sanctum
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!