API Reference

AXIUM Identity API

Service central d'identité pour les applications AXIUM. Il gère l'authentification via OAuth2 et Keycloak, ainsi que le chargement des rôles et permissions de chaque utilisateur. Cette page vous montre comment vous connecter, rafraîchir un token, et gérer chaque cas de réponse possible.

Présentation

AXIUM Identity valide votre application (client_id / client_secret), authentifie l'utilisateur via Keycloak, charge ses rôles et permissions, puis vous retourne un access_token et un refresh_token.

Démarrage rapide

Nouveau sur cette API ? Voici les 3 étapes à connaître avant de coder.

1

Obtenir un token

Envoyez vos identifiants à POST /api/oauth/token. Vous recevez un access_token valable 300 secondes.

2

Appeler l'API

Ajoutez le header Authorization: Bearer {access_token} à chaque requête protégée.

3

Rafraîchir avant expiration

Utilisez POST /api/oauth/refresh avec le refresh_token pour obtenir un nouveau couple de tokens sans redemander le mot de passe.

Flux d'authentification

  • L'application cliente fournit son client_id et client_secret.
  • AXIUM Identity valide l'application.
  • L'utilisateur est authentifié via Keycloak.
  • Les rôles et permissions sont chargés.
  • Un access_token et un refresh_token sont retournés.

Connexion utilisateur

Authentifie un utilisateur et retourne ses tokens, rôles et permissions.

POST /api/oauth/token

Paramètres

ParamètreTypeObligatoireDescription
client_idstringOuiIdentifiant public de l'application cliente.
client_secretstringOuiSecret privé fourni lors de la création de l'application.
usernamestringOuiEmail ou identifiant utilisateur.
passwordstringOuiMot de passe utilisateur.

Exemple de requête

Requête
POST /api/oauth/token
Content-Type: application/json

{
    "client_id": "axium-stock",
    "client_secret": "xxxxxxxx",
    "username": "byao@sifogroup.com",
    "password": "123456"
}

Réponses possibles

Cliquez sur un code pour voir le format exact retourné par l'API.

200 OK
{
    "success": true,
    "token_type": "Bearer",
    "access_token": "eyJhbGciOiJSU.....",
    "refresh_token": "eyJhbGciOiJI.....",
    "expires_in": 300,
    "user": {
        "id": 1,
        "email": "byao@sifogroup.com",
        "first_name": "Benjamin",
        "last_name": "YAO",
        "active": true
    },
    "roles": [
        "ROLE_USER",
        "ROLE_ADMIN",
        "ROLE_COMMERCIAL"
    ],
    "permissions": [
        "CREATE_USER",
        "CREATE_CARD",
        "CREATE_VOYAGE",
        "VIEW_USER_DASHBOAD"
    ],
    "permissionsWithDescriptions": [
        {
            "name": "CREATE_USER",
            "description": "Création d'un utilisateur ADMIN"
        },
        {
            "name": "CREATE_CARD",
            "description": "Création d'une carte carburant"
        },
        {
            "name": "CREATE_VOYAGE",
            "description": "Création d'un voyage"
        },
        {
            "name": "VIEW_USER_DASHBOAD",
            "description": "Consultation du tableau de bord Utilisateur"
        }
    ]
}
Pour un débutant : utilisez permissions si vous avez juste besoin de vérifier des droits dans votre code (ex. if permissions.includes('CREATE_CARD')). Utilisez permissionsWithDescriptions si vous devez afficher les droits à l'écran (ex. page de gestion des rôles), le champ description est déjà rédigé pour l'utilisateur final.
401 Unauthorized · INVALID_CLIENT
{
    "success": false,
    "error": {
        "code": "INVALID_CLIENT",
        "message": "Client inconnu.",
        "details": []
    }
}
Le client_id envoyé n'existe pas côté AXIUM Identity. Vérifiez qu'il correspond bien à celui de votre application.
401 Unauthorized · INVALID_CLIENT_SECRET
{
    "success": false,
    "error": {
        "code": "INVALID_CLIENT_SECRET",
        "message": "Client secret invalide.",
        "details": []
    }
}
Le client_id est correct mais le client_secret ne correspond pas.
401 Unauthorized · AUTHENTICATION_FAILED
{
    "success": false,
    "error": {
        "code": "AUTHENTICATION_FAILED",
        "message": "Identifiants incorrects.",
        "details": []
    }
}
Le username existe mais le password est incorrect.
401 Unauthorized · AUTHENTICATION_FAILED
{
    "success": false,
    "error": {
        "code": "AUTHENTICATION_FAILED",
        "message": "Utilisateur invalide.",
        "details": []
    }
}
Même code que ci-dessus (AUTHENTICATION_FAILED) mais message différent : ici le username ne correspond à aucun compte. Si vous distinguez les deux cas côté front, testez sur le champ message, pas seulement sur code.
403 Forbidden · APP_ACCESS_DENIED
{
    "success": false,
    "error": {
        "code": "APP_ACCESS_DENIED",
        "message": "Accès refusé. Votre compte ne dispose pas des autorisations requises pour utiliser cette application.",
        "details": []
    }
}
Les identifiants sont corrects, mais ce compte n'a pas le droit d'accéder à cette application cliente précise.

Rafraîchir un token

Génère un nouveau access_token à partir du refresh_token, sans redemander les identifiants.

POST /api/oauth/refresh

Paramètres

ParamètreTypeObligatoireDescription
refresh_tokenstringOuiToken de rafraîchissement obtenu lors de la connexion.

Exemple de requête

Requête
POST /api/oauth/refresh
Content-Type: application/json

{
    "refresh_token": "eyJhbGciOi..."
}

Réponse — 200 OK

200 OK
{
    "success": true,
    "token_type": "Bearer",
    "access_token": "eyJhbGciOi...",
    "refresh_token": "eyJhbGciOi...",
    "expires_in": 300
}
En cas d'échec, ce endpoint retourne le même format d'erreur commun décrit dans Format des erreurs (le plus fréquent étant un refresh_token expiré ou invalide).

Déconnexion

Révoque le refresh token et termine la session utilisateur côté Keycloak.

POST /api/oauth/logout

Paramètres

ParamètreTypeObligatoireDescription
refresh_tokenstringOuiRefresh token à invalider.

Exemple de requête

Requête
POST /api/oauth/logout
Content-Type: application/json

{
    "refresh_token": "eyJhbGciOi..."
}

Réponse — 200 OK

200 OK
{
    "success": true,
    "message": "Déconnexion réussie."
}

Utiliser le token

Toutes les API protégées nécessitent l'ajout du header HTTP suivant à chaque requête :

Header
Authorization: Bearer {access_token}

Créer un utilisateur

Crée un nouvel utilisateur et l'associe à l'application cliente appelante. Si un utilisateur possédant déjà cet email existe, il est mis à jour et l'application cliente lui est simplement ajoutée (aucune duplication de compte).

POST /api/user/create

Paramètres

ParamètreTypeObligatoireDescription
client_idstringOuiIdentifiant de l'application cliente qui sera associée à l'utilisateur.
emailstringOuiEmail de l'utilisateur. Sert aussi à détecter si l'utilisateur existe déjà.
firstNamestringOuiPrénom de l'utilisateur.
lastNamestringOuiNom de l'utilisateur.
phonestringNonNuméro de téléphone au format international (ex: +2250709502322).
passwordstringOuiMot de passe de l'utilisateur.

Exemple de requête

Requête
POST /api/user/create
Content-Type: application/json

{
    "client_id": "op0a1a84-f8a6-461a-graz1-fd32fdcbf2cb",
    "email": "byao@sifogroup.com",
    "firstName": "Benjamin",
    "lastName": "YAO",
    "phone": "+2250709502322",
    "password": "123456"
}

Réponses possibles

Cliquez sur un code pour voir le format exact retourné par l'API.

200 OK
{
    "success": true,
    "message": "Utilisateur créé avec succès.",
    "client": "Axium Stock",
    "user": {
        "id": 14,
        "email": "byao@sifogroup.com"
    }
}
Pour un débutant : ce cas se produit quand l'email fourni n'existe encore dans aucun compte AXIUM Identity. Un nouvel utilisateur est créé à la fois côté Keycloak et côté base AXIUM Identity, puis associé à l'application client_id fournie.
200 OK
{
    "success": true,
    "message": "Utilisateur modifié avec succès.",
    "client": "Axium Stock",
    "user": {
        "id": 7,
        "email": "byao@sifogroup.com"
    }
}
Ce cas se produit quand un compte avec cet email (ou ce keycloak_id) existe déjà. Le compte n'est pas dupliqué : l'application cliente client_id est simplement ajoutée à la liste des applications de l'utilisateur existant, et ses informations (nom, téléphone, etc.) sont mises à jour avec celles envoyées.
403 Forbidden
{
    "success": false,
    "message": "Client application invalide."
}
Le client_id envoyé n'existe pas côté AXIUM Identity.

Uploader un avatar

Permet à une application cliente de mettre à jour la photo de profil d'un utilisateur. Le fichier est stocké et traité entièrement côté AXIUM Identity — l'application cliente ne fait que transmettre le fichier reçu depuis son formulaire.

POST /api/user/avatar/upload
Ce endpoint attend une requête multipart/form-data (et non du JSON), car un fichier est envoyé.

Paramètres

ParamètreTypeObligatoireDescription
client_idstringOuiIdentifiant public de l'application cliente.
emailstringOuiEmail de l'utilisateur concerné.
avatarfileOuiFichier image. Formats acceptés : JPEG, PNG, WEBP. Taille max : 2 Mo.

Exemple de requête

Requête (multipart/form-data)
POST /api/user/avatar/upload
Content-Type: multipart/form-data

client_id: axium-stock
email: byao@sifogroup.com
avatar: (fichier binaire, ex: photo.jpg)

Réponses possibles

Cliquez sur un code pour voir le format exact retourné par l'API.

200 OK
{
    "success": true,
    "message": "Avatar mis à jour avec succès.",
    "client": "Axium Stock",
    "user": {
        "id": 1,
        "email": "byao@sifogroup.com",
        "avatar_url": "https://api.identity.optimumci.com/uploads/avatars/0190f3c2-....jpg"
    }
}
Pour un débutant : avatar_url est une URL directement utilisable dans un <img src="...">. L'ancien avatar de l'utilisateur (s'il existait) est automatiquement supprimé côté serveur.
400 Bad Request
{
    "success": false,
    "message": "Aucun fichier avatar fourni."
}
Le champ avatar est absent de la requête, ou n'a pas été envoyé comme fichier (type File, pas Text).
403 Forbidden
{
    "success": false,
    "message": "Client application invalide."
}
Le client_id envoyé n'existe pas côté AXIUM Identity.
404 Not Found
{
    "success": false,
    "message": "Utilisateur introuvable."
}
Aucun utilisateur ne correspond à l'email fourni.
422 Unprocessable Entity
{
    "success": false,
    "message": "L'image ne doit pas dépasser 2 Mo."
}
Le fichier envoyé dépasse 2 Mo, ou n'est pas dans un format accepté (seuls JPEG, PNG et WEBP sont autorisés). Le message varie selon la cause exacte.

Format des erreurs

Toutes les erreurs retournées par AXIUM Identity utilisent ce format JSON uniforme, quel que soit l'endpoint :

Format commun
{
    "success": false,
    "error": {
        "code": "ERROR_CODE",
        "message": "Message utilisateur",
        "details": []
    }
}
Astuce débutant : testez toujours success en premier dans votre code. S'il vaut false, allez lire error.code (stable, pour votre logique) et error.message (déjà en français, pour l'affichage à l'utilisateur).

Codes d'erreur possibles

CodeStatut HTTPMessageCause
INVALID_CLIENT401Client inconnu.client_id introuvable.
INVALID_CLIENT_SECRET401Client secret invalide.client_secret incorrect pour ce client_id.
AUTHENTICATION_FAILED401Identifiants incorrects.Mot de passe erroné.
AUTHENTICATION_FAILED401Utilisateur invalide.Utilisateur introuvable.
APP_ACCESS_DENIED403Accès refusé. Votre compte ne dispose pas des autorisations requises pour utiliser cette application.Compte valide mais non autorisé sur cette application cliente.

Codes HTTP

CodeDescription
200Opération réussie.
400Requête invalide ou paramètre manquant.
401Authentification échouée ou client invalide.
403Compte ou application non autorisé.
422Fichier invalide (format ou taille non conforme).
500Erreur interne du service AXIUM Identity.
Loading…
Loading the web debug toolbar…
Attempt #