Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Jak wdrożyć zgodę pacjenta z SMART on FHIR
Samouczek: SMART on FHIR z OAuth 2.1 i PKCE krok po kroku — discovery, rejestracja aplikacji, ekran zgody, wymiana tokenów, egzekwowanie zakresów, rotacja odświeżania i odwołanie — oraz co implementuje Anpheros.
SMART on FHIR to standardowy sposób, w jaki aplikacja uzyskuje zgodę osoby na dostęp do jej rekordu FHIR: OAuth 2.1 z PKCE do autoryzacji, zakresy określające dokładnie, co można odczytać lub zapisać, oraz dokument odkrywania informujący aplikację, dokąd ma się udać. Ten tutorial przeprowadzi przez cały przepływ z Anpheros, krok po kroku z curl: odkrywanie, rejestracja aplikacji, wysłanie osoby na ekran zgody, wymiana kodu, wywołanie API w ramach przyznanych zakresów, odświeżanie i co się dzieje, gdy osoba odwoła dostęp. Anpheros to backend SMART on FHIR: hostuje serwer autoryzacji, ekran zgody i serwer FHIR R4, dzięki czemu nie musisz tworzyć własnego interfejsu użytkownika logowania ani zgody.
Dlaczego zgoda, a nie tylko klucz API
Klucz API umożliwia dostęp do danych pacjentów, które Twój projekt utworzył. Istniejące rekordy pacjenta (jego własne dane, zebrane przez inne aplikacje, kliniki i laboratoria) są jego własnością i może nimi zarządzać. Dzięki SMART on FHIR:
- pacjent widzi, w swoim języku, która aplikacja prosi o dostęp, czego chce odczytać lub zapisać, w jakim celu i na jak długo;
- Twoja aplikacja otrzymuje dostęp tylko do tych typów zasobów i akcji, i tylko dla tego jednego rekordu;
- każdy dostęp jest rejestrowany i widoczny dla pacjenta, który może go w każdej chwili odwołać;
- zgoda jest również przechowywana jako zasób FHIR
Consent.
Model stojący za tym rozwiązaniem jest opisany w Healthcare API with patient consent i Consent and access model.
Krok 1: odkrywanie
curl https://platform.anpheros.com/fhir/R4/.well-known/smart-configuration
Odpowiedź zawiera listę punktów końcowych i informacje o tym, co serwer obsługuje (skrócone):
{"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"]}
Biblioteki klienckie SMART odczytują ten dokument i nie wymagają żadnej dodatkowej konfiguracji.
Krok 2: Rejestracja aplikacji
W panelu administracyjnym otwórz swój projekt i dodaj aplikację wraz z jej URI przekierowania. Alternatywnie, możesz to zrobić za pomocą Admin API:
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"
}'
{"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", …}
Użyj public dla aplikacji mobilnych i przeglądarkowych, które nie mogą przechowywać sekretu i polegają na PKCE. Użyj confidential dla serwera; jego client_secret jest wyświetlany tylko raz. Nazwa, cel i link do polityki prywatności to informacje, które użytkownik widzi na ekranie zgody.
Krok 3: Przekierowanie użytkownika do ekranu zgody
Utwórz parę PKCE. Weryfikator pozostaje u Ciebie; podróżuje tylko jego skrót (hash):
VERIFIER=$(openssl rand -base64 64 | tr -d '=+/\n' | cut -c1-64)
CHALLENGE=$(printf %s "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
Następnie otwórz ten adres w przeglądarce użytkownika (dodano podziały wierszy dla czytelności):
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
Poproś tylko o to, czego potrzebujesz. Ta aplikacja odczytuje wyniki laboratoryjne i diagnozy, nic więcej. offline_access zwraca token odświeżający, dzięki czemu użytkownik nie musi ponownie zatwierdzać dostępu co 30 minut.
Użytkownik loguje się do Anpheros, czyta żądanie w języku prostym, wybiera, który rekord udostępnić (własny, członka rodziny, którym się opiekuje, lub ten, który Twoja aplikacja utworzyła dla niego) oraz jak długo ma trwać dostęp, a następnie zezwala lub odmawia. Użytkownik wraca do Twojego URI przekierowania:
https://cardio.example/callback?code=…&state=8c1e…
Sprawdź, czy state jest wartością, którą wysłałeś wcześniej, przed użyciem kodu.
Krok 4: wymiana kodu na tokeny
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
{"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_…"}
scopewymienia przyznane uprawnienia. Zachowaj je wraz z tokenami i wyświetlaj tylko funkcje, które obejmują.patientto identyfikator rekordu dla Twojej aplikacji. Jest on parzysty: inna aplikacja widzi tę samą osobę pod innym identyfikatorem.id_tokento token OpenID Connect, którego polefhirUsernazywa zasób pacjenta.- Kod działa raz i tylko z pasującym
code_verifier.
Krok 5: Wywołanie API w ramach zakresów
curl "https://platform.anpheros.com/fhir/R4/Observation?patient=$PATIENT&category=laboratory" -H "Authorization: Bearer $ACCESS_TOKEN"
Wyniki laboratoryjne wracają jak zwykle. Poproś o coś spoza przyznanego zakresu, na przykład o leki:
curl "https://platform.anpheros.com/fhir/R4/MedicationStatement?patient=$PATIENT" -H "Authorization: Bearer $ACCESS_TOKEN"
{"resourceType": "OperationOutcome", "issue": [{"severity": "error", "code": "forbidden",
"diagnostics": "The consent behind this token does not allow 's' on MedicationStatement."}]}
Jest to 403. Wyszukiwania w ramach przyznanego zakresu są również filtrowane: z Observation.rs?category=laboratory, wyszukiwanie wszystkich obserwacji zwraca tylko laboratoryjne. Żaden inny pacjent nie istnieje dla tego tokenu (404). Widok REST (/v1) i API kontekstu stosują te same zakresy.
Krok 6: odświeżanie
Tokeny dostępu są ważne przez 30 minut. Tokeny odświeżania są ważne przez 30 dni i rotują przy każdym użyciu:
curl -X POST https://platform.anpheros.com/oauth/token \
-d grant_type=refresh_token -d client_id=client_Hg6CknNkYlMgN190 -d refresh_token=$REFRESH_TOKEN
Otrzymujesz nowy token dostępu i nowy token odświeżania. Natychmiast zapisz nowy token. Ponowne użycie starego tokena odświeżania jest traktowane jako kradzież: kończy się błędem 400 i unieważnia całe przyznanie.
Krok 7: odwołanie
Osoba może w dowolnym momencie odwołać Twój dostęp z poziomu Anpheros, a Ty możesz go odwołać samodzielnie, na przykład gdy osoba odłączy się w Twojej aplikacji:
curl -X POST https://platform.anpheros.com/oauth/revoke -d token=$REFRESH_TOKEN -d client_id=client_Hg6CknNkYlMgN190
Od tego momentu każde wywołanie z tym upoważnieniem zwraca 401. Obsłuż to, pokazując osobie, że połączenie zostało zakończone i oferując ponowne połączenie. Zasubskrybuj webhook consent.revoked, aby dowiedzieć się o tym bez czekania na nieudane wywołanie.
Z użyciem SDK
SDK w językach TypeScript i Dart wykonują za Ciebie kroki od 3 do 6: OAuthFlow.authorizeUrl z wygenerowaną parą PKCE, exchange przy wywołaniu zwrotnym oraz automatyczne odświeżanie z rotacją. Pełne przykłady: Jak zbudować aplikację AI w służbie zdrowia z backendem FHIR (TypeScript) i Jak zbudować aplikację w służbie zdrowia z użyciem Fluttera (Dart).
Co implementuje Anpheros
| Część SMART | W Anpheros |
|---|---|
| Discovery | /.well-known/smart-configuration na bazie FHIR, z obsługiwanymi punktami końcowymi, zakresami i metodami PKCE |
| Launch | uruchomienie samodzielne (aplikacja uruchamia się, a następnie prosi o dostęp); uruchomienie z poziomu systemu klinicznego EHR nie jest oferowane |
| Autoryzacja | OAuth 2.1 z wymaganym PKCE, przepływ kodu autoryzacji |
| Zakresy | zakresy pacjenta SMART v2, patient/<Resource>.<cruds> z filtrami kategorii, plus openid i fhirUser |
| Tożsamość | OpenID Connect id_token wskazujący pacjenta jako zasób FHIR |
| Zgoda | hostowany ekran zgody w języku pacjenta, z czasem trwania wybranym przez pacjenta, odzwierciedlony jako FHIR Consent |
| Tokeny | 30-minutowe tokeny dostępu, rotujące 30-dniowe tokeny odświeżania powiązane ze zgodą, odwołanie |
| Zgodność | oświadczenie o możliwościach deklaruje usługę bezpieczeństwa SMART; grupa "Standalone Launch" zestawu testowego Inferno SMART App Launch STU2 przechodzi 22 z 22 testów (uruchomienie z 28 września 2026); pozostałe grupy i zestawy testowe Inferno nie zostały uruchomione |
Pisanie działa w ten sam sposób: pisanie zakresów (patient/Observation.c, .u, .d) pozwala aplikacji tworzyć, aktualizować lub usuwać dane w rekordzie. Wszystko, co jest zapisywane, zawiera Twoją aplikację jako autora, ponowne próby z kluczem idempotencji nigdy nie duplikują pomiaru, a usunięcia są miękkie i zachowują historię (Medical data API).
Czego jeszcze nie ma
- Uruchomienie EHR (aplikacja otwierana z poziomu systemu szpitalnego z kontekstem uruchomienia).
system/zakresów (scopes) dla usług backendowych; organizacje zamiast tego używają kluczy API.- Eksport danych masowych (
$export); dostępny jest eksport$everythingdla pacjenta.
Są one wymienione wraz z pozostałymi w sekcji Wersjonowanie i wycofywanie, a oświadczenie o możliwościach (capability statement) jest zawsze autorytatywnym źródłem informacji.
Często zadawane pytania
Czym jest SMART on FHIR?
Otwarty standard, zbudowany na OAuth 2.0/2.1 i OpenID Connect, który definiuje, w jaki sposób aplikacja prosi o dostęp do rekordu FHIR, jakie zakresy (scopes) opisują ten dostęp i jak serwer reklamuje swoje punkty końcowe (endpoints). Dowolna biblioteka klienta obsługująca SMART może korzystać z dowolnego serwera obsługującego SMART.
Czy potrzebuję PKCE?
Tak. Anpheros wymaga PKCE z S256 dla każdego przepływu kodu autoryzacyjnego, zarówno dla klientów publicznych, jak i poufnych. Zapobiega to wykorzystaniu przechwyconego kodu autoryzacyjnego przez kogokolwiek innego.
Co się stanie, jeśli osoba odmówi?
Osoba zostanie przekierowana z powrotem do Twojego URI przekierowania (redirect URI) z error=access_denied i Twoim state, ale bez kodu. Wyjaśnij, czego potrzebuje dana funkcja i pozwól jej spróbować ponownie; wywołania spoza przyznanego dostępu (grant) zawsze zwracają 403.
Czy rodzic może wyrazić zgodę dla dziecka?
Tak. Na ekranie zgody osoba może wybrać rekord, o który się troszczy, na przykład dziecka, jeśli jest on powiązany z jej kontem. Przyznany dostęp (grant) dotyczy tylko tego rekordu.
Powiązane
- Uwierzytelnianie i OAuth: klucze API, tokeny i ich okresy ważności w szczegółach
- API medyczne z zgodą pacjenta: jak zgoda wpływa na projekt Twojej aplikacji
- Model zgody i dostępu
- Platforma FHIR
- Tworzenie aplikacji medycznej
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card