# Cum să implementați consimțământul pacientului cu SMART on FHIR

> Tutorial: SMART on FHIR cu OAuth 2.1 și PKCE pas cu pas — descoperire, înregistrare aplicație, ecran de consimțământ, schimb de token-uri, scope-uri impuse, rotație refresh și revocare — și ce implementează Anpheros.

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

**SMART on FHIR este metoda standard prin care o aplicație obține permisiunea unei persoane de a accesa înregistrarea sa FHIR: OAuth 2.1 cu PKCE pentru autorizare, scope-uri care specifică exact ce poate fi citit sau scris și un document de descoperire care informează aplicația unde să meargă.** Acest tutorial parcurge întregul flux împotriva Anpheros, pas cu pas cu `curl`: descoperire, înregistrarea unei aplicații, trimiterea persoanei către ecranul de consimțământ, schimbarea codului, apelarea API-ului în cadrul scope-urilor acordate, reîmprospătare și ce se întâmplă când persoana revocă accesul. Anpheros este backend-ul SMART on FHIR: găzduiește serverul de autorizare, ecranul de consimțământ și serverul FHIR R4, astfel încât nu trebuie să scrieți propria interfață de login sau consimțământ.

## De ce consimțământ și nu doar o cheie API

O cheie API ajunge la pacienții pe care proiectul dvs. i-a creat. Un dosar existent al unei persoane (propriile sale date, colectate de alte aplicații, clinici și laboratoare) este al acesteia pentru a-l partaja. Cu SMART on FHIR:

- persoana vede, în limba sa, ce aplicație întreabă, ce dorește să citească sau să scrie, în ce scop și pentru cât timp;
- aplicația dvs. primește doar acele tipuri de resurse și acțiuni, și doar pentru acel unic dosar;
- fiecare acces este înregistrat și vizibil persoanei, care îl poate revoca oricând;
- permisiunea este, de asemenea, stocată ca o resursă FHIR `Consent`.

Modelul din spatele acestuia este descris în [Healthcare API with patient consent](https://developers.anpheros.com/ro/guides/healthcare-api-patient-consent) și [Consent and access model](https://developers.anpheros.com/ro/guides/consent).

## Pasul 1: descoperire

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

Răspunsul listează endpoint-urile și ce suportă serverul (abreviat):

```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"]}
```

Bibliotecile client SMART citesc acest document și nu necesită nicio altă configurare.

## Pasul 2: înregistrați aplicația

În [dashboard](https://platform.anpheros.com/dashboard/), deschideți proiectul și adăugați o aplicație cu URI-ul său de redirecționare. Sau prin Admin API:

```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", …}
```

Utilizați `public` pentru aplicații mobile și de browser, care nu pot păstra un secret și se bazează pe PKCE. Utilizați `confidential` pentru un server; `client_secret` său este afișat o singură dată. Numele, scopul și linkul de confidențialitate sunt ceea ce persoana vede pe ecranul de consimțământ.

## Pasul 3: trimite persoana la ecranul de consimțământ

Creează o pereche PKCE. Verificatorul rămâne la tine; doar hash-ul său este 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 '=')
```

Apoi deschide această adresă în browserul persoanei (linii noi adăugate pentru lizibilitate):

```
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
```

Cere minimul de care ai nevoie. Această aplicație citește rezultatele de laborator și diagnosticele, nimic altceva. `offline_access` oferă un token de reîmprospătare (refresh token), astfel încât persoana nu trebuie să aprobe din nou la fiecare 30 de minute.

Persoana se autentifică în Anpheros, citește cererea în limbaj clar, alege ce înregistrare să partajeze (propria sa, a unui membru al familiei de care are grijă sau cea creată de aplicația ta pentru ea) și cât timp durează accesul, apoi permite sau refuză. Persoana se întoarce la URI-ul tău de redirecționare (redirect URI):

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

Verifică dacă `state` este valoarea pe care ai trimis-o înainte de a utiliza codul.

## Pasul 4: schimbați codul pentru tokenuri

```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` listează ce a fost acordat. Păstrați-l cu tokenurile și afișați doar funcționalitățile pe care le acoperă.
- `patient` este ID-ul înregistrării pentru aplicația dumneavoastră. Este pairwise: o altă aplicație vede aceeași persoană sub un ID diferit.
- `id_token` este un token OpenID Connect al cărui claim `fhirUser` numește resursa pacientului.
- Codul funcționează o singură dată și numai cu `code_verifier` corespunzător.

## Pasul 5: Apelați API-ul în cadrul domeniilor (scopes)

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

Rezultatele de laborator revin ca de obicei. Cereți ceva în afara grantului, cum ar fi medicamente:

```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."}]}
```

Acesta este un `403`. Căutările din cadrul grantului sunt, de asemenea, filtrate: cu `Observation.rs?category=laboratory`, o căutare pentru toate observațiile returnează doar cele de laborator. Orice alt pacient nu există pentru acest token (`404`). Vizualizarea REST (`/v1`) și [API-ul de context](https://developers.anpheros.com/ro/guides/llm-healthcare-data) aplică aceleași domenii.

## Pasul 6: refresh

Tokenurile de acces durează 30 de minute. Tokenurile de refresh durează 30 de zile și se rotesc la fiecare utilizare:

```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
```

Obțineți un nou token de acces și un nou token de refresh. Stocați-l pe cel nou imediat. Reutilizarea unui token de refresh vechi este considerată furt: eșuează cu `400` și revocă întregul grant.

## Pasul 7: revocare

Persoana poate revoca accesul dumneavoastră din Anpheros în orice moment, iar dumneavoastră îl puteți revoca singur, de exemplu, atunci când se deconectează în aplicația dumneavoastră:

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

De atunci, fiecare apel cu acel grant va răspunde `401`. Gestionați acest lucru arătând persoanei că conexiunea s-a încheiat și oferindu-i posibilitatea de a se conecta din nou. Abonați-vă la [webhook-ul](https://developers.anpheros.com/ro/guides/webhooks) `consent.revoked` pentru a afla fără a aștepta un apel eșuat.

## Cu SDK-urile

[SDK-urile TypeScript și Dart](https://developers.anpheros.com/ro/guides/sdks) efectuează pașii de la 3 la 6 pentru dumneavoastră: `OAuthFlow.authorizeUrl` cu o pereche PKCE generată, `exchange` la apelul de retur (callback) și reîmprospătare automată cu rotație. Exemple complete: [Cum să construiești o aplicație AI pentru sănătate cu un backend FHIR](https://developers.anpheros.com/ro/guides/build-ai-healthcare-app) (TypeScript) și [Cum să construiești o aplicație pentru sănătate cu Flutter](https://developers.anpheros.com/ro/guides/healthcare-app-flutter) (Dart).

## Ce implementează Anpheros

| Parte SMART | În Anpheros |
|---|---|
| Discovery | `/.well-known/smart-configuration` pe baza FHIR, cu endpoint-urile, scope-urile și metodele PKCE suportate |
| Launch | standalone launch (aplicația pornește, apoi cere acces); EHR launch din interiorul unui sistem clinic nu este oferit |
| Autorizare | OAuth 2.1 cu PKCE obligatoriu, flux de autorizare prin cod |
| Scopes | SMART v2 patient scopes, `patient/<Resource>.<cruds>` cu filtre de categorie, plus `openid` și `fhirUser` |
| Identitate | un OpenID Connect `id_token` numind pacientul ca resursă FHIR |
| Consimțământ | un ecran de consimțământ găzduit în limba pacientului, cu durata aleasă de pacient, oglindit ca un FHIR `Consent` |
| Tokens | token-uri de acces de 30 de minute, token-uri de reîmprospătare rotative de 30 de zile legate de consimțământ, revocare |
| Conformance | declarația de capabilități declară serviciul de securitate SMART; grupul "Standalone Launch" al kit-ului de testare Inferno SMART App Launch STU2 trece 22 din 22 de teste (rulare din 28 septembrie 2026); celelalte grupuri și kit-uri de testare Inferno nu au fost rulate |

Scrierea funcționează la fel: scrieți scope-uri (`patient/Observation.c`, `.u`, `.d`) care permit aplicației dvs. să creeze, să actualizeze sau să șteargă în cadrul înregistrării. Tot ce este scris poartă aplicația dvs. ca autor, reîncercările cu o cheie de idempotență nu duplicatează niciodată o măsurătoare, iar ștergerile sunt soft și păstrează istoricul ([Medical data API](https://developers.anpheros.com/ro/guides/medical-data-api)).

## Ce lipsește încă

- Lansare EHR (aplicația deschisă din interiorul unui sistem spitalicesc cu un context de lansare).
- `system/` scope-uri pentru servicii backend; organizațiile folosesc în schimb chei API.
- Export de date în masă (`$export`); `$everything` pe un pacient este disponibil.

Acestea sunt listate împreună cu restul în [Versioning și deprecieri](https://developers.anpheros.com/ro/guides/versioning), iar declarația de capabilități este întotdeauna sursa autorizată.

## Întrebări frecvente

### Ce este SMART on FHIR?
Un standard deschis, construit pe OAuth 2.0/2.1 și OpenID Connect, care definește cum o aplicație solicită acces la o înregistrare FHIR, ce scopuri descriu acel acces și cum serverul își publică punctele finale. Orice bibliotecă client compatibilă SMART poate utiliza orice server compatibil SMART.

### Am nevoie de PKCE?
Da. Anpheros necesită PKCE cu `S256` pentru fiecare flux de cod de autorizare, atât pentru clienți publici, cât și confidențiali. Acesta împiedică utilizarea unui cod de autorizare interceptat de către oricine altcineva.

### Ce se întâmplă dacă persoana refuză?
Aceasta se întoarce la URI-ul dvs. de redirecționare cu `error=access_denied` și `state`, și fără cod. Explicați ce necesită funcționalitatea și lăsați-i să încerce din nou; apelurile în afara unei autorizări răspund întotdeauna cu `403`.

### Poate un părinte să își dea consimțământul pentru un copil?
Da. Pe ecranul de consimțământ, o persoană poate alege o înregistrare de care îi pasă, cum ar fi cea a unui copil, dacă aceasta este legată de contul său. Autorizarea se aplică numai acelei înregistrări.

## Conexe

- [Autentificare și OAuth](https://developers.anpheros.com/ro/guides/authentication): Chei API, tokenuri și durate de viață în detaliu
- [API pentru sănătate cu consimțământul pacientului](https://developers.anpheros.com/ro/guides/healthcare-api-patient-consent): cum modifică consimțământul designul aplicației dumneavoastră
- [Model de consimțământ și acces](https://developers.anpheros.com/ro/guides/consent)
- [Platformă FHIR](https://developers.anpheros.com/ro/guides/fhir)
- [Construiți o aplicație pentru sănătate](https://developers.anpheros.com/ro/guides/build-a-healthcare-app)
