> ## Documentation Index
> Fetch the complete documentation index at: https://docs.finkare.io/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth 2.1

> Guide complet pour implémenter l'authentification OAuth 2.1 avec Client Credentials et Authorization Code + PKCE.

## Vue d'ensemble

L'API Finkare supporte OAuth 2.1 avec trois grant types :

| Grant Type                    | Usage                            | Refresh Token |
| ----------------------------- | -------------------------------- | ------------- |
| **Client Credentials**        | Machine-to-machine (serveur)     | Non           |
| **Authorization Code + PKCE** | Application tierce (utilisateur) | Oui           |
| **Refresh Token**             | Renouvellement d'access token    | Oui           |

## Client Credentials

Le flow le plus simple, pour les intégrations serveur-à-serveur sans intervention utilisateur.

### 1. Obtenir un access token

```bash theme={null}
curl -X POST https://api.finkare.io/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "fk_client_mgen_prod",
    "client_secret": "fk_secret_xyz789abc123def456",
    "scope": "invoices:read invoices:write payments:read workflow:read"
  }'
```

Vous pouvez aussi passer les credentials via Basic Auth :

```bash theme={null}
curl -X POST https://api.finkare.io/api/oauth/token \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic $(echo -n 'fk_client_mgen_prod:fk_secret_xyz789abc123def456' | base64)" \
  -d '{ "grant_type": "client_credentials", "scope": "invoices:read payments:read" }'
```

### 2. Réponse

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJma19jbGllbnRfbWdlbl9wcm9kIiwic2NvcGUiOiJpbnZvaWNlczpyZWFkIHBheW1lbnRzOnJlYWQiLCJleHAiOjE3NDQxMjAwMDB9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "invoices:read invoices:write payments:read workflow:read"
}
```

### 3. Utiliser le token

```bash theme={null}
curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  https://api.finkare.io/api/v1/invoices
```

<Note>
  Les tokens Client Credentials expirent après **1 heure** (3600 secondes). Demandez un nouveau token avant expiration.
</Note>

## Authorization Code + PKCE

Pour les applications qui nécessitent le consentement explicite de l'utilisateur. Obligatoire pour les intégrations qui accèdent à des données multi-entreprises.

### 1. Générer le PKCE challenge

```typescript theme={null}
import crypto from 'crypto';

// Générer le code_verifier (43-128 caractères)
const codeVerifier = crypto.randomBytes(32).toString('base64url');

// Calculer le code_challenge (SHA-256)
const codeChallenge = crypto
  .createHash('sha256')
  .update(codeVerifier)
  .digest('base64url');

console.log('code_verifier:', codeVerifier);
console.log('code_challenge:', codeChallenge);
```

### 2. Rediriger vers l'écran de consentement

```
GET https://api.finkare.io/api/oauth/authorize
  ?response_type=code
  &client_id=fk_client_votre_app
  &redirect_uri=https://votre-app.com/callback
  &scope=invoices:read+payments:read+workflow:read
  &state=random_csrf_protection_string
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
```

L'utilisateur voit un écran de consentement Finkare listant les scopes demandés. Après approbation, il est redirigé vers votre `redirect_uri` avec un `code` :

```
https://votre-app.com/callback?code=auth_abc123xyz&state=random_csrf_protection_string
```

### 3. Échanger le code contre un token

```bash theme={null}
curl -X POST https://api.finkare.io/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "client_id": "fk_client_votre_app",
    "client_secret": "fk_secret_votre_secret",
    "code": "auth_abc123xyz",
    "redirect_uri": "https://votre-app.com/callback",
    "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
  }'
```

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "invoices:read payments:read workflow:read",
  "refresh_token": "fk_rt_refresh_abc123xyz789"
}
```

### 4. Renouveler avec le refresh token

```bash theme={null}
curl -X POST https://api.finkare.io/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "client_id": "fk_client_votre_app",
    "refresh_token": "fk_rt_refresh_abc123xyz789"
  }'
```

## Révocation

Révoquez un token compromis (opération idempotente) :

```bash theme={null}
curl -X POST https://api.finkare.io/api/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{ "token": "eyJhbGciOiJSUzI1NiIs..." }'
```

## Introspection

Vérifiez la validité d'un token et ses métadonnées :

```bash theme={null}
curl -X POST https://api.finkare.io/api/oauth/introspect \
  -H "Content-Type: application/json" \
  -d '{ "token": "eyJhbGciOiJSUzI1NiIs..." }'
```

```json theme={null}
{
  "active": true,
  "client_id": "fk_client_mgen_prod",
  "scope": "invoices:read payments:read",
  "token_type": "Bearer"
}
```

## Discovery (RFC 8414)

Les métadonnées OAuth sont disponibles via le endpoint de discovery :

```
GET https://api.finkare.io/.well-known/oauth-authorization-server
```

Cela permet aux outils compatibles (y compris les clients MCP) de découvrir automatiquement les endpoints OAuth.

## Bonnes pratiques

1. **Moindre privilège** : ne demandez que les scopes strictement nécessaires
2. **Refresh proactif** : renouvelez le token quelques minutes avant son expiration
3. **Stockage sécurisé** : ne stockez jamais les tokens dans le localStorage — utilisez des cookies httpOnly ou un backend
4. **State parameter** : vérifiez toujours le `state` dans le callback pour prévenir les attaques CSRF
5. **PKCE obligatoire** : seule la méthode S256 est acceptée (conformité OAuth 2.1)
