Aller au contenu principal

🔐 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 IDNomDescriptionPermissions
3AgentUtilisateur de baseAccès limité à ses propres données
4Chef d'ÉquipeSuperviseur niveau 1Validation niveau 1, gestion d'équipe
5SuperviseurSuperviseur niveau 2Validation 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

CodeDescriptionCause
200SuccèsOpération réussie
400Bad RequestDonnées de requête invalides
401UnauthorizedToken manquant, invalide ou expiré
403ForbiddenPermissions insuffisantes
404Not FoundRessource non trouvée
500Internal Server ErrorErreur 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.