# Comment implémenter le consentement du patient avec SMART on FHIR

> Tutoriel : SMART on FHIR avec OAuth 2.1 et PKCE étape par étape — découverte, enregistrement d'application, écran de consentement, échange de jeton, portée appliquée, rotation de rafraîchissement et révocation — et ce qu'Anpheros implémente.

Source: https://developers.anpheros.com/fr/guides/smart-on-fhir-backend

**SMART on FHIR est la manière standard pour une application d'obtenir la permission d'une personne d'accéder à son dossier FHIR : OAuth 2.1 avec PKCE pour l'autorisation, des portées qui indiquent exactement ce qui peut être lu ou écrit, et un document de découverte qui indique à l'application où aller.** Ce tutoriel exécute l'intégralité du flux contre Anpheros, étape par étape avec `curl` : découverte, enregistrement d'une application, envoi de la personne à l'écran de consentement, échange du code, appel de l'API dans les portées accordées, rafraîchissement, et ce qui se passe lorsque la personne révoque l'accès. Anpheros est le backend SMART on FHIR : il héberge le serveur d'autorisation, l'écran de consentement et le serveur FHIR R4, vous n'avez donc pas à écrire votre propre interface utilisateur de connexion ou de consentement.

## Pourquoi le consentement et pas seulement une clé d'API

Une clé d'API atteint les patients que votre projet a créés. L'enregistrement existant d'une personne (ses propres données, collectées par d'autres applications, cliniques et laboratoires) est le sien à partager. Avec SMART on FHIR :

- la personne voit, dans sa langue, quelle application demande, ce qu'elle veut lire ou écrire, dans quel but et pour combien de temps ;
- votre application n'obtient que ces types de ressources et actions, et uniquement pour cet enregistrement unique ;
- chaque accès est consigné et visible par la personne, qui peut le révoquer à tout moment ;
- l'autorisation est également stockée sous forme de ressource FHIR `Consent`.

Le modèle sous-jacent est décrit dans [API de santé avec consentement du patient](https://developers.anpheros.com/fr/guides/healthcare-api-patient-consent) et [Modèle de consentement et d'accès](https://developers.anpheros.com/fr/guides/consent).

## Étape 1 : découverte

```bash
curl https://platform.anpheros.com/fhir/R4/.well-known/smart-configuration
```

La réponse liste les points de terminaison et ce que le serveur prend en charge (abrégé) :

```json
{"issuer": "https://platform.anpheros.com",
 "authorization_endpoint": "https://platform.anpheros.com/oauth/authorize",
 "token_endpoint": "https://platform.anpheros.com/oauth/token",
 "revocation_endpoint": "https://platform.anpheros.com/oauth/revoke",
 "code_challenge_methods_supported": ["S256"],
 "scopes_supported": ["patient/*.rs", "patient/Patient.r", "patient/Observation.rs", "patient/Observation.rs?category=laboratory",
                      "patient/Observation.rs?category=vital-signs", "patient/Observation.c", "patient/Condition.rs",
                      "patient/MedicationStatement.rs", "patient/DocumentReference.rs", "patient/AllergyIntolerance.rs",
                      "offline_access", "launch/patient", "openid", "fhirUser"],
 "capabilities": ["launch-standalone", "client-public", "client-confidential-symmetric", "permission-patient",
                  "permission-offline", "context-standalone-patient", "sso-openid-connect"]}
```

Les bibliothèques clientes SMART lisent ce document et n'ont besoin d'aucune autre configuration.

## Étape 2 : enregistrer votre application

Dans le [tableau de bord](https://platform.anpheros.com/dashboard/), ouvrez votre projet et ajoutez une application avec son URI de redirection. Ou via l'API d'administration :

```bash
curl -X POST https://platform.anpheros.com/admin/projects/$PROJECT/applications \
     -H "Authorization: Bearer $FIREBASE_ID_TOKEN" -H "Content-Type: application/json" -d '{
  "name": "CardioAI", "client_type": "public",
  "redirect_uris": ["https://cardio.example/callback"],
  "purpose": "cardiology follow-up", "privacy_url": "https://cardio.example/privacy"
}'
```

```json
{"id": "app_…", "name": "CardioAI", "client_type": "public", "client_id": "client_Hg6CknNkYlMgN190", "client_secret": null,
 "redirect_uris": ["https://cardio.example/callback"], "purpose": "cardiology follow-up", "status": "active", …}
```

Utilisez `public` pour les applications mobiles et de navigateur, qui ne peuvent pas conserver de secret et s'appuient sur PKCE. Utilisez `confidential` pour un serveur ; son `client_secret` est affiché une seule fois. Le nom, le but et le lien de confidentialité sont ce que la personne voit sur l'écran de consentement.

## Étape 3 : rediriger la personne vers l'écran de consentement

Créez une paire PKCE. Le vérificateur reste avec vous ; seul son hachage est transmis :

```bash
VERIFIER=$(openssl rand -base64 64 | tr -d '=+/\n' | cut -c1-64)
CHALLENGE=$(printf %s "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
```

Ouvrez ensuite cette adresse dans le navigateur de la personne (les sauts de ligne sont ajoutés pour la lisibilité) :

```
https://platform.anpheros.com/oauth/authorize?response_type=code
  &client_id=client_Hg6CknNkYlMgN190
  &redirect_uri=https://cardio.example/callback
  &scope=openid fhirUser patient/Observation.rs?category=laboratory patient/Condition.rs offline_access
  &state=8c1e…               ← a random value you check on return
  &code_challenge=$CHALLENGE&code_challenge_method=S256
  &purpose=treatment&lang=en
```

Demandez le minimum nécessaire. Cette application lit les résultats de laboratoire et les diagnostics, rien d'autre. `offline_access` donne un jeton de rafraîchissement, ainsi la personne n'a pas à approuver à nouveau toutes les 30 minutes.

La personne se connecte à Anpheros, lit la demande en langage clair, choisit quel dossier partager (le sien, celui d'un membre de sa famille dont elle s'occupe, ou celui que votre application a créé pour elle) et la durée de l'accès, puis autorise ou refuse. Elle revient à votre URI de redirection :

```
https://cardio.example/callback?code=…&state=8c1e…
```

Vérifiez que `state` est la valeur que vous avez envoyée avant d'utiliser le code.

## Étape 4 : Échanger le code contre des jetons

```bash
curl -X POST https://platform.anpheros.com/oauth/token \
  -d grant_type=authorization_code -d client_id=client_Hg6CknNkYlMgN190 \
  -d code=$CODE -d code_verifier=$VERIFIER -d redirect_uri=https://cardio.example/callback
```

```json
{"access_token": "at_…", "token_type": "Bearer", "expires_in": 1800,
 "scope": "patient/Observation.rs?category=laboratory patient/Condition.rs openid fhirUser offline_access",
 "patient": "82bfd321-6a4d-4aea-943a-a62f4d81d419", "grant_id": "grant_…",
 "id_token": "eyJ…", "refresh_token": "rt_…"}
```

- `scope` liste ce qui a été accordé. Gardez-le avec les jetons et affichez uniquement les fonctionnalités qu'il couvre.
- `patient` est l'identifiant de l'enregistrement pour votre application. Il est par paire : une autre application voit la même personne sous un identifiant différent.
- `id_token` est un jeton OpenID Connect dont la revendication `fhirUser` nomme la ressource patient.
- Le code fonctionne une fois, et uniquement avec le `code_verifier` correspondant.

## Étape 5 : Appeler l'API dans les limites des scopes

```bash
curl "https://platform.anpheros.com/fhir/R4/Observation?patient=$PATIENT&category=laboratory" -H "Authorization: Bearer $ACCESS_TOKEN"
```

Les résultats de laboratoire reviennent comme d'habitude. Demandez quelque chose en dehors de la portée du grant, comme les médicaments :

```bash
curl "https://platform.anpheros.com/fhir/R4/MedicationStatement?patient=$PATIENT" -H "Authorization: Bearer $ACCESS_TOKEN"
```

```json
{"resourceType": "OperationOutcome", "issue": [{"severity": "error", "code": "forbidden",
  "diagnostics": "The consent behind this token does not allow 's' on MedicationStatement."}]}
```

C'est un `403`. Les recherches à l'intérieur du grant sont également filtrées : avec `Observation.rs?category=laboratory`, une recherche de toutes les observations ne retourne que celles de laboratoire. Aucun autre patient n'existe pour ce token (`404`). La vue REST (`/v1`) et l'[API de contexte](https://developers.anpheros.com/fr/guides/llm-healthcare-data) appliquent les mêmes scopes.

## Étape 6 : Actualisation

Les jetons d'accès sont valides pendant 30 minutes. Les jetons d'actualisation sont valides pendant 30 jours et sont renouvelés à chaque utilisation :

```bash
curl -X POST https://platform.anpheros.com/oauth/token \
  -d grant_type=refresh_token -d client_id=client_Hg6CknNkYlMgN190 -d refresh_token=$REFRESH_TOKEN
```

Vous obtenez un nouveau jeton d'accès et un nouveau jeton d'actualisation. Stockez le nouveau immédiatement. La réutilisation d'un ancien jeton d'actualisation est considérée comme un vol : elle échoue avec `400` et révoque l'intégralité de l'autorisation.

## Étape 7 : Révocation

La personne peut révoquer votre accès depuis Anpheros à tout moment, et vous pouvez le révoquer vous-même, par exemple lorsqu'elle se déconnecte dans votre application :

```bash
curl -X POST https://platform.anpheros.com/oauth/revoke -d token=$REFRESH_TOKEN -d client_id=client_Hg6CknNkYlMgN190
```

À partir de ce moment, chaque appel avec cette autorisation répondra `401`. Gérez cela en montrant à la personne que la connexion est terminée et en lui proposant de se reconnecter. Abonnez-vous au webhook `consent.revoked` [webhook](https://developers.anpheros.com/fr/guides/webhooks) pour être informé sans attendre un appel échoué.

## Avec les SDKs

Les [SDKs TypeScript et Dart](https://developers.anpheros.com/fr/guides/sdks) effectuent les étapes 3 à 6 pour vous : `OAuthFlow.authorizeUrl` avec une paire PKCE générée, `exchange` lors du callback, et un rafraîchissement automatique avec rotation. Exemples complets : [Comment construire une application de santé IA avec un backend FHIR](https://developers.anpheros.com/fr/guides/build-ai-healthcare-app) (TypeScript) et [Comment construire une application de santé avec Flutter](https://developers.anpheros.com/fr/guides/healthcare-app-flutter) (Dart).

## Ce qu'implémente Anpheros

| Partie de SMART | Dans Anpheros |
|---|---|
| Découverte | `/.well-known/smart-configuration` sur la base FHIR, avec les endpoints, scopes et méthodes PKCE supportés |
| Lancement | Lancement autonome (l'application démarre, puis demande l'accès) ; le lancement depuis un système clinique (EHR) n'est pas proposé |
| Autorisation | OAuth 2.1 avec PKCE requis, flux de code d'autorisation |
| Scopes | Scopes patient SMART v2, `patient/<Resource>.<cruds>` avec filtres par catégorie, plus `openid` et `fhirUser` |
| Identité | un OpenID Connect `id_token` nommant le patient comme une ressource FHIR |
| Consentement | un écran de consentement hébergé dans la langue du patient, avec la durée choisie par le patient, reflété comme un `Consent` FHIR |
| Tokens | Tokens d'accès de 30 minutes, tokens de rafraîchissement rotatifs de 30 jours liés au consentement, révocation |
| Conformité | la déclaration de capacité déclare le service de sécurité SMART ; le groupe "Standalone Launch" du kit de test Inferno SMART App Launch STU2 réussit 22 tests sur 22 (exécution du 28 septembre 2026) ; les autres groupes et kits de test Inferno n'ont pas été exécutés |

L'écriture fonctionne de la même manière : écrire des scopes (`patient/Observation.c`, `.u`, `.d`) permet à votre application de créer, mettre à jour ou supprimer dans le dossier. Tout ce qui est écrit porte votre application comme auteur, les tentatives avec une clé d'idempotence ne dupliquent jamais une mesure, et les suppressions sont douces et conservent l'historique ([Medical data API](https://developers.anpheros.com/fr/guides/medical-data-api)).

## Ce qui n'est pas encore disponible

- Lancement EHR (application ouverte depuis un système hospitalier avec un contexte de lancement).
- `system/` scopes pour les services backend ; les organisations utilisent des clés API à la place.
- Exportation de données en masse (`$export`) ; l'exportation `$everything` sur un patient est disponible.

Ces éléments sont listés avec le reste dans [Versioning et obsolescence](https://developers.anpheros.com/fr/guides/versioning), et la déclaration de capacité est toujours la source faisant autorité.

## Foire aux questions

### Qu'est-ce que SMART on FHIR ?
Une norme ouverte, basée sur OAuth 2.0/2.1 et OpenID Connect, qui définit comment une application demande l'accès à un dossier FHIR, quels scopes décrivent cet accès, et comment le serveur annonce ses points d'accès. Toute bibliothèque client compatible SMART peut utiliser tout serveur compatible SMART.

### Ai-je besoin de PKCE ?
Oui. Anpheros exige PKCE avec `S256` pour chaque flux de code d'autorisation, pour les clients publics et confidentiels. Cela empêche qu'un code d'autorisation intercepté soit utilisé par quelqu'un d'autre.

### Que se passe-t-il si la personne refuse ?
Elle retourne à votre URI de redirection avec `error=access_denied` et votre `state`, et sans code. Expliquez ce dont la fonctionnalité a besoin et laissez-la réessayer ; les appels en dehors d'une autorisation répondent toujours `403`.

### Un parent peut-il donner son consentement pour un enfant ?
Oui. Sur l'écran de consentement, une personne peut choisir un dossier qui lui tient à cœur, comme celui d'un enfant, s'il est lié à son compte. L'autorisation s'applique uniquement à ce dossier.

## Liens connexes

- [Authentification et OAuth](https://developers.anpheros.com/fr/guides/authentication) : clés API, jetons et durées de vie en détail
- [API de santé avec consentement du patient](https://developers.anpheros.com/fr/guides/healthcare-api-patient-consent) : comment le consentement modifie la conception de votre application
- [Modèle de consentement et d'accès](https://developers.anpheros.com/fr/guides/consent)
- [Plateforme FHIR](https://developers.anpheros.com/fr/guides/fhir)
- [Créer une application de santé](https://developers.anpheros.com/fr/guides/build-a-healthcare-app)
