> For the complete documentation index, see [llms.txt](https://ouvretaferme.gitbook.io/ouvretaferme/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ouvretaferme.gitbook.io/ouvretaferme/authentification/oauth2.md).

# OAuth2 (applications tierces)

Ce mode s'adresse aux applications qui agissent **pour le compte d'une structure**, avec l'accord explicite d'un de ses administrateurs. Ouvretaferme utilise le flux **Authorization Code avec PKCE**.

{% hint style="info" %}
**Accès sur demande.** L'enregistrement des applications n'est pas encore en libre-service. [Contactez-nous](https://asso.ouvretaferme.org/nous-contacter) pour obtenir votre `client_id`, en indiquant l'adresse de retour (`redirect_uri`) de votre application et les scopes dont elle a besoin.
{% endhint %}

## Le flux pas à pas

### 1. Préparer PKCE

Tirez au hasard un `code_verifier` de 43 à 128 caractères, puis calculez le `code_challenge`, encodage base64url sans remplissage du SHA-256 du `code_verifier`. Gardez le `code_verifier` pour l'étape 4.

### 2. Rediriger vers l'écran d'autorisation

```
https://www.ouvretaferme.org/api/oauth/authorize
  ?response_type=code
  &client_id=<votre-client-id>
  &redirect_uri=<votre-redirect-uri>
  &scope=production:read commercialisation:read
  &state=<valeur-aléatoire>
  &code_challenge=<code-challenge>
  &code_challenge_method=S256
```

| Paramètre               | Rôle                                                                                     |
| ----------------------- | ---------------------------------------------------------------------------------------- |
| `response_type`         | Toujours `code`                                                                          |
| `client_id`             | L'identifiant de votre application, que nous vous avons communiqué                       |
| `redirect_uri`          | L'adresse de retour déclarée pour votre application, à l'identique                       |
| `scope`                 | Les scopes demandés, séparés par des espaces, parmi ceux déclarés pour votre application |
| `state`                 | Une valeur aléatoire que vous vérifiez au retour, contre la falsification de requête     |
| `code_challenge`        | Le `code_challenge` calculé à l'étape 1                                                  |
| `code_challenge_method` | Toujours `S256`                                                                          |

La personne doit être connectée à Ouvretaferme. L'écran lui fait choisir la structure à laquelle le jeton donnera accès, parmi celles qu'elle administre et dont l'abonnement ouvre l'API, et passe ce choix quand il n'y en a qu'une. Votre application n'a donc pas à connaître les structures de ses utilisateurs.

### 3. Recevoir le code

L'écran présente les scopes demandés, que la personne accepte ou refuse en bloc. Ouvretaferme redirige ensuite vers votre `redirect_uri` avec `code` et `state`, ou avec `error=access_denied` en cas de refus. Le code n'est valable qu'**une minute**.

### 4. Échanger le code contre un jeton

```bash
curl https://www.ouvretaferme.org/api/oauth/token \
  -d grant_type=authorization_code \
  -d client_id=<votre-client-id> \
  -d redirect_uri=<votre-redirect-uri> \
  -d code=<code> \
  -d code_verifier=<code-verifier>
```

```json
{
  "structure": {
    "id": 7,
    "name": "Jardins de Tallende"
  },
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "...",
  "refresh_token": "..."
}
```

### 5. Appeler l'API

Le jeton s'envoie comme une clé API personnelle, dans l'en-tête `Authorization: Bearer`. Il est rattaché à la structure choisie sur l'écran d'autorisation, que la réponse nomme dans `structure`, quels que soient les scopes accordés. Une application reliée à plusieurs structures range ses jetons par `structure.id`, qui ne change jamais. Pour en relier une autre, la personne repasse par cet écran.

## Durée de vie et renouvellement

Le jeton d'accès vit **une heure**. Le jeton de renouvellement, reçu en même temps, vit **un mois** et en obtient un nouveau sans repasser par l'écran d'autorisation :

```bash
curl https://www.ouvretaferme.org/api/oauth/token \
  -d grant_type=refresh_token \
  -d client_id=<votre-client-id> \
  -d refresh_token=<refresh-token>
```

Chaque renouvellement rend aussi un nouveau jeton de renouvellement, qui remplace le précédent, ainsi que la même `structure`.

Un administrateur de la structure peut retirer l'autorisation à tout moment depuis l'écran des clés d'API de sa structure : le jeton d'accès cesse alors de fonctionner et le renouvellement échoue. Le jeton cesse aussi de fonctionner quand la personne qui a autorisé l'application n'administre plus la structure. Dans les deux cas, votre application propose à la personne de se reconnecter.

## Erreurs

Les routes `/api/oauth/authorize` et `/api/oauth/token` suivent la norme OAuth2 et rendent leurs erreurs sous la forme `{"error": "...", "error_description": "..."}`. Les routes de l'API rendent les leurs sous la forme décrite dans [Erreurs](/ouvretaferme/authentification/errors.md).
