Nous développerons une application complète d’authentification REST API avec Sanctum en suivant un guide simple et étape par étape.
Table des matières : [Masquer]
- 1 Qu’est-ce qu’une API ?
- 1.1 Qu’est-ce que Laravel Sanctum ?
- 1.2 Étape 1 : Installer Laravel 11
- 1.3 Étape 2 : Installer Sanctum API
- 1.4 Étape 3 : Configuration de Sanctum
- 1.5 Étape 4 : Ajouter une table et un modèle pour les produits
- 1.6 Étape 5 : Créer des routes API
- 1.7 Étape 6 : Créer les fichiers de contrôleurs
- 1.8 Étape 7 : Lancer l’application Laravel
Qu’est-ce qu’une API ?
Une API (Application Programming Interface) est simplement un moyen de communication entre deux ou plusieurs programmes informatiques.
Les API sont également utilisées pour le développement d’applications web et mobiles. Ainsi, créer une REST API est essentiel pour tout développeur d’applications web ou mobiles.
Qu’est-ce que Laravel Sanctum ?
Laravel Sanctum est un package d’authentification pour les applications Laravel, offrant un système d’authentification léger et facile à utiliser pour les applications monopages (SPA), les applications mobiles et autres projets basés sur des APIs. Il fournit une authentification par jeton, soit en utilisant JSON Web Tokens (JWT), soit via des tokens API, permettant une authentification sécurisée sans la complexité des systèmes basés sur des sessions. Sanctum simplifie la configuration de l’authentification par token, permettant aux développeurs de se concentrer sur la construction de leurs applications plutôt que sur les détails complexes de l’authentification.
Nous utiliserons Laravel Sanctum pour développer des APIs simples (single-page applications) généralement construites avec React JS, Angular ou Vue JS.
Installer une application Laravel 11.
Installer le package composer Sanctum pour l’authentification API.
Créer des APIs pour l’enregistrement et la connexion des utilisateurs.
Créer une REST API pour les produits nécessitant une authentification par token utilisateur.
Étapes pour configurer Sanctum REST API avec Laravel
Installer Laravel 11
Installer Sanctum API
Configurer Sanctum
Ajouter une table et un modèle pour les produits
Créer des routes API
Créer les fichiers de contrôleurs
Lancer l’application Laravel
Étape 1 : Installer Laravel 11
composer create-project laravel/laravel example-app
Étape 2 : Installer Sanctum API
Dans Laravel 11, par défaut, le fichier api.php pour les routes API n’est pas inclus.
Exécutez simplement la commande suivante pour installer Sanctum avec le fichier api.php :
php artisan install:api
Étape 3 : Configuration de Sanctum
Dans cette étape, nous configurons trois fichiers principaux : le modèle, le fournisseur de services et le fichier de configuration auth. Les modifications incluent :
Ajouter la classe HasApiTokens de Sanctum dans le modèle utilisateur.
Configurer l’authentification API dans le fichier auth.php.
// app/Models/User.php
<?php
namespace App\Models;
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',
];
}
}
Étape 4 : Ajouter une table et un modèle pour les produits
Créez une migration pour la table des produits avec la commande suivante :
php artisan make:migration create_products_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('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('detail');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('products');
}
};
Après avoir créé la table, exécutez la commande suivante pour appliquer la migration :
php artisan migrate
Ensuite, créez un modèle pour gérer les produits.
// app/Models/Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'detail'
];
}
Étape 5 : Créer des routes API
Ajoutez des routes pour les APIs d’inscription, de connexion et de gestion des produits dans le fichier routes/api.php.
// routes/api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\API\RegisterController;
use App\Http\Controllers\API\ProductController;
Route::controller(RegisterController::class)->group(function(){
Route::post('register', 'register');
Route::post('login', 'login');
});
Route::middleware('auth:sanctum')->group( function () {
Route::resource('products', ProductController::class);
});
Étape 6 : Créer les fichiers de contrôleurs
Créez trois contrôleurs :
BaseController pour les réponses communes (succès et erreurs).
RegisterController pour gérer l’inscription et la connexion des utilisateurs.
ProductController pour gérer les produits (création, mise à jour, suppression, liste et détail).
// app/Http/Controllers/API/BaseController.php
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;
class BaseController extends Controller
{
/**
* success response method.
*
* @return \Illuminate\Http\Response
*/
public function sendResponse($result, $message)
{
$response = [
'success' => true,
'data' => $result,
'message' => $message,
];
return response()->json($response, 200);
}
/**
* return error response.
*
* @return \Illuminate\Http\Response
*/
public function sendError($error, $errorMessages = [], $code = 404)
{
$response = [
'success' => false,
'message' => $error,
];
if(!empty($errorMessages)){
$response['data'] = $errorMessages;
}
return response()->json($response, $code);
}
}
// app/Http/Controllers/API/RegisterController.php
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Validator;
use Illuminate\Http\JsonResponse;
class RegisterController extends BaseController
{
/**
* Register api
*
* @return \Illuminate\Http\Response
*/
public function register(Request $request): JsonResponse
{
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
'c_password' => 'required|same:password',
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$input = $request->all();
$input['password'] = bcrypt($input['password']);
$user = User::create($input);
$success['token'] = $user->createToken('MyApp')->plainTextToken;
$success['name'] = $user->name;
return $this->sendResponse($success, 'User register successfully.');
}
/**
* Login api
*
* @return \Illuminate\Http\Response
*/
public function login(Request $request): JsonResponse
{
if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')->plainTextToken;
$success['name'] = $user->name;
return $this->sendResponse($success, 'User login successfully.');
}
else{
return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
}
}
}
// app/Http/Controllers/API/ProductController.php
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Models\Product;
use Validator;
use App\Http\Resources\ProductResource;
use Illuminate\Http\JsonResponse;
class ProductController extends BaseController
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(): JsonResponse
{
$products = Product::all();
return $this->sendResponse(ProductResource::collection($products), 'Products retrieved successfully.');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request): JsonResponse
{
$input = $request->all();
$validator = Validator::make($input, [
'name' => 'required',
'detail' => 'required'
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$product = Product::create($input);
return $this->sendResponse(new ProductResource($product), 'Product created successfully.');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id): JsonResponse
{
$product = Product::find($id);
if (is_null($product)) {
return $this->sendError('Product not found.');
}
return $this->sendResponse(new ProductResource($product), 'Product retrieved successfully.');
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Product $product): JsonResponse
{
$input = $request->all();
$validator = Validator::make($input, [
'name' => 'required',
'detail' => 'required'
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$product->name = $input['name'];
$product->detail = $input['detail'];
$product->save();
return $this->sendResponse(new ProductResource($product), 'Product updated successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Product $product): JsonResponse
{
$product->delete();
return $this->sendResponse([], 'Product deleted successfully.');
}
}
Étape 7 : Lancer l’application Laravel
php artisan make:resource ProductResource
// app/Http/Resources/ProductResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'detail' => $this->detail,
'created_at' => $this->created_at->format('d/m/Y'),
'updated_at' => $this->updated_at->format('d/m/Y'),
];
}
}
Une fois toutes les étapes complétées, lancez l’application Laravel avec la commande suivante :
php artisan serve
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
]
Testez les APIs en utilisant Postman ou un autre outil similaire. Assurez-vous d’inclure les en-têtes suivants pour les APIs nécessitant un token :
Routes disponibles :
API d’inscription : POST /api/register
API de connexion : POST /api/login
Liste des produits : GET /api/products
Créer un produit : POST /api/products
Détails d’un produit : GET /api/products/{id}
Mettre à jour un produit : PUT /api/products/{id}
Supprimer un produit : DELETE /api/products/{id}