---
title: Authentification
excerpt: Connexion, inscription, déconnexion, changement de token et endpoints d'identité pour les API centrale et workspace.
order: 2
---

## Vue d'ensemble

CX-Engine utilise des **tokens Bearer OAuth 2.0**. Les tokens sont scopés à la plateforme centrale ou à un workspace spécifique. Utilisez `POST /api/switch-to` pour changer de scope sans vous reconnecter.

---

## OAuth 2.0

CX-Engine prend en charge deux types d'attribution OAuth 2.0 pour l'accès délégué et les communications machine-à-machine :

| Type d'attribution | Cas d'usage |
|---|---|
| **Authorization Code** | Accès délégué interactif via redirection navigateur |
| **Client Credentials** | Accès serveur-à-serveur sans interaction utilisateur |

> **Prérequis :** Pour utiliser un flux OAuth 2.0, vous devez d'abord créer un client OAuth dans votre tableau de bord CX-Engine. Cela vous fournit un `client_id` et un `client_secret` requis pour tous les types d'attribution.

### Authorization Code Grant

Utilisé lorsque votre application agit pour le compte d'un utilisateur. L'utilisateur approuve l'accès dans son navigateur et votre application reçoit un code d'autorisation à échanger contre des tokens.

**Étape 1 : Rediriger l'utilisateur**

`GET /oauth/authorize`

| Paramètre | Type | Description |
|---|---|---|
| `client_id` | string | L'identifiant client de votre application |
| `redirect_uri` | string | URI de redirection après autorisation |
| `response_type` | string | Doit être `code` |
| `scope` | string | Liste de scopes séparés par des espaces (optionnel) |
| `state` | string | Chaîne aléatoire pour la protection CSRF (recommandé) |

> Le `redirect_uri` doit correspondre exactement à l'une des URIs de redirection enregistrées sur votre client OAuth. Les requêtes avec une URI non enregistrée seront rejetées.

L'utilisateur voit un écran d'approbation. En cas d'approbation, il est redirigé vers votre `redirect_uri` avec un paramètre `code`.

**Étape 2 : Échanger le code contre des tokens**

`POST /oauth/token`

| Champ | Type | Description |
|---|---|---|
| `grant_type` | string | `authorization_code` |
| `client_id` | string | Votre identifiant client |
| `client_secret` | string | Votre secret client |
| `redirect_uri` | string | Doit correspondre à l'URI utilisée à l'étape 1 |
| `code` | string | Le code d'autorisation reçu |

**Réponse `200`**

```json
{
  "token_type": "Bearer",
  "expires_in": 31536000,
  "access_token": "eyJ0eXAiOiJKV1Q...",
  "refresh_token": "def50200..."
}
```

---

### Client Credentials Grant

Utilisé pour les communications serveur-à-serveur sans interaction utilisateur.

`POST /oauth/token`

| Champ | Type | Description |
|---|---|---|
| `grant_type` | string | `client_credentials` |
| `client_id` | string | Votre identifiant client |
| `client_secret` | string | Votre secret client |
| `scope` | string | Liste de scopes séparés par des espaces (optionnel) |

**Réponse `200`**

```json
{
  "token_type": "Bearer",
  "expires_in": 31536000,
  "access_token": "eyJ0eXAiOiJKV1Q..."
}
```

> Les tokens client credentials ne comprennent pas de refresh token.

---

### Rafraîchir un token

`POST /oauth/token`

| Champ | Type | Description |
|---|---|---|
| `grant_type` | string | `refresh_token` |
| `refresh_token` | string | Le refresh token d'une réponse précédente |
| `client_id` | string | Votre identifiant client |
| `client_secret` | string | Votre secret client |
| `scope` | string | Doit être identique ou un sous-ensemble des scopes d'origine |

**Réponse `200`**

```json
{
  "token_type": "Bearer",
  "expires_in": 31536000,
  "access_token": "eyJ0eXAiOiJKV1Q...",
  "refresh_token": "def50200..."
}
```

> **Rotation du refresh token :** Chaque appel à cet endpoint invalide le refresh token précédent et en émet un nouveau. Vous devez persister le `refresh_token` retourné à chaque réponse ; réutiliser un ancien refresh token entraînera une erreur.

---

### Révoquer un token

`DELETE /oauth/tokens/{token_id}`

**En-têtes :** `Authorization: Bearer {access_token}`

**Réponse `204`** : token révoqué.

---

## API centrale

### POST /api/login

Authentifie un utilisateur sur la plateforme centrale et retourne un token Bearer scopé central.

**Corps de la requête**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `email` | string | oui | Adresse email de l'utilisateur |
| `password` | string | oui | Mot de passe |

**Réponse `200`**

```json
{
  "message": "success",
  "token": "eyJ0eXAiOiJKV1Q...",
  "user": { "id": 1, "name": "Jane Doe", "email": "jane@exemple.com" },
  "workspaces": [...],
  "pending_invites": [...]
}
```

**Réponse `401`**

```json
{ "response": "invalid username and/or password." }
```

---

### POST /api/register

Crée un nouveau compte utilisateur et retourne un token Bearer scopé central.

**Corps de la requête**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `name` | string | oui | Nom complet |
| `email` | string | oui | Adresse email |
| `password` | string | oui | Mot de passe |
| `phone` | string | non | Numéro de téléphone |
| `mobile_phone` | string | non | Numéro de mobile |

**Réponse `200`**

```json
{
  "message": "success",
  "token": "eyJ0eXAiOiJKV1Q...",
  "user": { ... },
  "workspaces": [],
  "pending_invites": []
}
```

**Réponse `422`** : email déjà utilisé

```json
{ "message": "An user with this e-mail address already exists." }
```

---

### POST /api/logout

Révoque tous les tokens de l'utilisateur authentifié sur la plateforme centrale et tous les workspaces.

**En-têtes :** `Authorization: Bearer {token-central}`

**Réponse `200`**

```json
{ "message": "success" }
```

---

### GET /api/whoami

Retourne l'identité de l'utilisateur actuellement authentifié ainsi que ses workspaces.

**En-têtes :** `Authorization: Bearer {token-central}`

**Réponse `200`**

```json
{
  "message": "success",
  "user": { "id": 1, "name": "Jane Doe", "email": "jane@exemple.com" },
  "workspaces": [...],
  "current_workspace": null
}
```

Lorsque l'appel est effectué avec un token workspace, `current_workspace` inclut le nom du workspace, le groupe, les rôles et les permissions :

```json
{
  "current_workspace": {
    "name": "Acme Corp",
    "group": "admin",
    "roles": ["manager"],
    "permissions": ["customer.view", "customer.create"]
  }
}
```

---

### POST /api/switch-to

Émet un nouveau token scopé vers un workspace différent, ou de retour vers le central, sans nécessiter de reconnexion.

**En-têtes :** `Authorization: Bearer {token-actuel}`

**Corps : basculer vers un workspace**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `workspace_id` | string | oui* | ID du workspace cible |

**Corps : revenir au central**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `central` | boolean | oui* | Passer `true` pour revenir au scope central |

*L'un de `workspace_id` ou `central` est requis.

**Réponse `200`**

```json
{
  "message": "success",
  "user": { ... },
  "workspace": {
    "id": "acme",
    "name": "Acme Corp",
    "group": "admin",
    "roles": ["manager"],
    "permissions": ["customer.view", ...]
  },
  "domains": ["acme.cx-engine.app"],
  "token": "eyJ0eXAiOiJKV1Q..."
}
```

**Réponse `403`** : workspace inaccessible

```json
{ "message": "You do not have access to this workspace." }
```

---

## API workspace

### POST /api/login *(workspace)*

Authentifie un utilisateur sur un workspace spécifique et retourne un token Bearer scopé workspace. Envoyez cette requête vers le sous-domaine du workspace.

**Corps de la requête**

| Champ | Type | Requis |
|---|---|---|
| `email` | string | oui |
| `password` | string | oui |

**Réponse `200`**

```json
{
  "message": "success",
  "token": "eyJ0eXAiOiJKV1Q...",
  "user": { ... }
}
```

---

### POST /api/logout *(workspace)*

Révoque uniquement le token workspace actuel.

**En-têtes :** `Authorization: Bearer {token-workspace}`

**Réponse `200`**

```json
{ "message": "success" }
```
