🔐 API Authentication
Documentation complète de l'API d'authentification de Commerce Tracking.
🎯 Vue d'ensemble
Le système d'authentification utilise JWT (JSON Web Tokens) avec un système de rôles hiérarchique pour contrôler l'accès aux différentes fonctionnalités du système.
Fonctionnalités
- Authentification par nom d'utilisateur/mot de passe
- Génération et validation de tokens JWT
- Gestion des sessions utilisateur
- Contrôle d'accès basé sur les rôles
- Rafraîchissement des tokens
- Déconnexion sécurisée
🔑 Système de rôles
Hiérarchie des rôles
| Role ID | Nom | Description | Permissions |
|---|---|---|---|
| 3 | Agent | Utilisateur de base | Accès limité à ses propres données |
| 4 | Chef d'Équipe | Superviseur niveau 1 | Validation niveau 1, gestion d'équipe |
| 5 | Superviseur | Superviseur niveau 2 | Validation niveau 2, vue globale |
Permissions par rôle
interface RolePermissions {
agent: {
collections: ['create', 'read', 'update', 'delete'], // Own only
reports: ['read'], // Own only
profile: ['read', 'update']
},
teamManager: {
collections: ['create', 'read', 'update', 'delete', 'validate_level_1'],
reports: ['read', 'generate'],
users: ['read'], // Team members only
profile: ['read', 'update']
},
supervisor: {
collections: ['create', 'read', 'update', 'delete', 'validate_level_1', 'validate_level_2'],
reports: ['read', 'generate', 'export'],
users: ['read', 'create', 'update'],
system: ['monitor', 'configure'],
profile: ['read', 'update']
}
}
📡 Endpoints d'authentification
Base URL
http://localhost:3005
Headers requis
Content-Type: application/json
Authentification
Authorization: Bearer <jwt-token>
🔐 Endpoints
POST /auth/login
Connexion utilisateur et génération du token JWT.
Request:
POST /auth/login
Content-Type: application/json
{
"username": "john.doe",
"password": "securePassword123"
}
Response Success (200):
{
"success": true,
"message": "Connexion réussie",
"result": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"token_type": "Bearer",
"user": {
"id": 123,
"username": "john.doe",
"email": "john.doe@example.com",
"role_id": 4,
"country_id": 1,
"actor": {
"id": 456,
"actor_role": "Trade Officer",
"first_name": "John",
"last_name": "Doe"
}
}
},
"errors": null,
"except": null
}
Response Error (401):
{
"success": false,
"message": "Identifiants invalides",
"result": null,
"errors": ["Nom d'utilisateur ou mot de passe incorrect"],
"except": null
}
POST /auth/logout
Déconnexion utilisateur et invalidation du token.
Request:
POST /auth/logout
Authorization: Bearer <jwt-token>
Content-Type: application/json
Response Success (200):
{
"success": true,
"message": "Déconnexion réussie",
"result": null,
"errors": null,
"except": null
}
POST /auth/refresh
Rafraîchissement du token d'accès.
Request:
POST /auth/refresh
Content-Type: application/json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response Success (200):
{
"success": true,
"message": "Token rafraîchi avec succès",
"result": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"token_type": "Bearer"
},
"errors": null,
"except": null
}
GET /auth/profile
Récupération du profil utilisateur connecté.
Request:
GET /auth/profile
Authorization: Bearer <jwt-token>
Response Success (200):
{
"success": true,
"message": "Profil récupéré avec succès",
"result": {
"id": 123,
"username": "john.doe",
"email": "john.doe@example.com",
"role_id": 4,
"role_name": "Chef d'Équipe",
"country_id": 1,
"country_name": "République Démocratique du Congo",
"is_active": true,
"last_login": "2024-01-15T10:30:00Z",
"created_at": "2024-01-01T08:00:00Z",
"actor": {
"id": 456,
"actor_role": "Trade Officer",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone": "+243 123 456 789",
"is_active": true
}
},
"errors": null,
"except": null
}
POST /auth/validate
Validation d'un token JWT.
Request:
POST /auth/validate
Content-Type: application/json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response Success (200):
{
"success": true,
"message": "Token valide",
"result": {
"isValid": true,
"user": {
"id": 123,
"username": "john.doe",
"role_id": 4,
"expires_at": "2024-01-15T11:30:00Z"
}
},
"errors": null,
"except": null
}
🔒 Structure du token JWT
Payload du token
interface JwtPayload {
sub: number; // User ID
username: string; // Username
email: string; // User email
role_id: number; // Role ID
country_id: number; // Country ID
actor?: { // Actor information (optional)
id: number;
actor_role: string;
first_name: string;
last_name: string;
};
iat: number; // Issued at
exp: number; // Expires at
jti: string; // JWT ID
}
Exemple de token décodé
{
"sub": 123,
"username": "john.doe",
"email": "john.doe@example.com",
"role_id": 4,
"country_id": 1,
"actor": {
"id": 456,
"actor_role": "Trade Officer",
"first_name": "John",
"last_name": "Doe"
},
"iat": 1642248000,
"exp": 1642251600,
"jti": "uuid-string"
}
🛡️ Gestion des erreurs
Codes d'erreur HTTP
| Code | Description | Cause |
|---|---|---|
| 200 | Succès | Opération réussie |
| 400 | Bad Request | Données de requête invalides |
| 401 | Unauthorized | Token manquant, invalide ou expiré |
| 403 | Forbidden | Permissions insuffisantes |
| 404 | Not Found | Ressource non trouvée |
| 500 | Internal Server Error | Erreur serveur interne |
Messages d'erreur courants
{
"success": false,
"message": "Token expiré",
"result": null,
"errors": ["Le token JWT a expiré. Veuillez vous reconnecter."],
"except": null
}
{
"success": false,
"message": "Token invalide",
"result": null,
"errors": ["Le token JWT fourni n'est pas valide."],
"except": null
}
{
"success": false,
"message": "Permissions insuffisantes",
"result": null,
"errors": ["Vous n'avez pas les permissions nécessaires pour effectuer cette action."],
"except": null
}
🔧 Utilisation dans les applications client
JavaScript/TypeScript
class AuthService {
private baseUrl = 'http://localhost:3005';
private token: string | null = null;
async login(username: string, password: string) {
const response = await fetch(`${this.baseUrl}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, password }),
});
const data = await response.json();
if (data.success) {
this.token = data.result.access_token;
localStorage.setItem('access_token', this.token);
localStorage.setItem('refresh_token', data.result.refresh_token);
}
return data;
}
async logout() {
if (this.token) {
await fetch(`${this.baseUrl}/auth/logout`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json',
},
});
this.token = null;
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
}
}
async getProfile() {
if (!this.token) {
throw new Error('No token available');
}
const response = await fetch(`${this.baseUrl}/auth/profile`, {
headers: {
'Authorization': `Bearer ${this.token}`,
},
});
return await response.json();
}
async refreshToken() {
const refreshToken = localStorage.getItem('refresh_token');
if (!refreshToken) {
throw new Error('No refresh token available');
}
const response = await fetch(`${this.baseUrl}/auth/refresh`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ refresh_token: refreshToken }),
});
const data = await response.json();
if (data.success) {
this.token = data.result.access_token;
localStorage.setItem('access_token', this.token);
}
return data;
}
}
cURL Examples
# Login
curl -X POST http://localhost:3005/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"john.doe","password":"securePassword123"}'
# Get profile
curl -X GET http://localhost:3005/auth/profile \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Logout
curl -X POST http://localhost:3005/auth/logout \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json"
# Refresh token
curl -X POST http://localhost:3005/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token":"YOUR_REFRESH_TOKEN"}'
🔐 Sécurité
Bonnes pratiques
- HTTPS obligatoire en production
- Tokens avec expiration courte (1 heure)
- Refresh tokens avec expiration longue (7 jours)
- Rotation des secrets JWT régulière
- Logout côté serveur pour invalider les tokens
- Rate limiting sur les endpoints de login
Configuration de sécurité
// Configuration JWT recommandée
{
secret: process.env.JWT_SECRET, // Secret fort et unique
expiresIn: '1h', // Expiration courte
refreshExpiresIn: '7d', // Refresh token plus long
algorithm: 'HS256', // Algorithme sécurisé
issuer: 'commerce-tracking', // Émetteur identifié
audience: 'commerce-clients' // Audience spécifique
}
Cette API d'authentification fournit une base sécurisée pour l'accès au système Commerce Tracking avec une gestion fine des permissions basée sur les rôles utilisateur.