Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Как реализовать согласие пациента с SMART on FHIR
Руководство: SMART on FHIR с OAuth 2.1 и PKCE шаг за шагом — обнаружение, регистрация приложения, экран согласия, обмен токенами, принудительное применение областей действия, ротация обновления и отзыв — и что реализовано в Anpheros.
SMART on FHIR — это стандартный способ получения приложением разрешения человека на доступ к его FHIR-записи: OAuth 2.1 с PKCE для авторизации, области действия (scopes), которые точно указывают, что можно читать или записывать, и документ обнаружения (discovery document), который сообщает приложению, куда обращаться. Это учебное пособие пошагово демонстрирует весь процесс работы с Anpheros, включая curl: обнаружение, регистрацию приложения, отправку человека на экран согласия, обмен кодом, вызов API в рамках предоставленных областей действия, обновление и действия при отзыве доступа. Anpheros — это бэкенд SMART on FHIR: он размещает сервер авторизации, экран согласия и сервер FHIR R4, поэтому вам не нужно писать собственный интерфейс входа или согласия.
Почему согласие, а не просто API-ключ
API-ключ предоставляет доступ к данным пациентов, созданным вашим проектом. Существующие записи человека (его собственные данные, собранные другими приложениями, клиниками и лабораториями) он может предоставлять для совместного использования. С помощью SMART on FHIR:
- человек видит на своем языке, какое приложение запрашивает доступ, что оно хочет прочитать или записать, для какой цели и на какой срок;
- ваше приложение получает только те типы ресурсов и действия, и только для этой одной записи;
- каждый доступ регистрируется и виден человеку, который может отозвать его в любое время;
- разрешение также хранится как ресурс FHIR
Consent.
Модель, лежащая в основе этого, описана в Healthcare API with patient consent и Consent and access model.
Шаг 1: обнаружение
curl https://platform.anpheros.com/fhir/R4/.well-known/smart-configuration
Ответ содержит список конечных точек и информацию о том, что поддерживает сервер (сокращенно):
{"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"]}
Клиентские библиотеки SMART считывают этот документ и не требуют дополнительной настройки.
Шаг 2: регистрация вашего приложения
На панели управления откройте ваш проект и добавьте приложение с его URI перенаправления. Или через 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", …}
Используйте public для мобильных и браузерных приложений, которые не могут хранить секрет и полагаются на PKCE. Используйте confidential для сервера; его client_secret отображается один раз. Название, назначение и ссылка на политику конфиденциальности — это то, что пользователь видит на экране согласия.
Шаг 3: Перенаправление пользователя на экран согласия
Создайте пару PKCE. Верификатор остается у вас; передается только его хеш:
VERIFIER=$(openssl rand -base64 64 | tr -d '=+/\n' | cut -c1-64)
CHALLENGE=$(printf %s "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
Затем откройте этот адрес в браузере пользователя (переносы строк добавлены для удобства чтения):
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
Запрашивайте только самое необходимое. Это приложение считывает результаты лабораторных исследований и диагнозы, ничего более. offline_access выдает токен обновления, поэтому пользователю не придется подтверждать согласие каждые 30 минут.
Пользователь входит в Anpheros, читает запрос на понятном языке, выбирает, какую запись предоставить (свою собственную, запись члена семьи, за которым он ухаживает, или запись, созданную вашим приложением для него), и на какой срок предоставляется доступ, затем разрешает или запрещает. Пользователь возвращается по вашему URI перенаправления:
https://cardio.example/callback?code=…&state=8c1e…
Убедитесь, что state соответствует значению, которое вы отправили ранее, прежде чем использовать код.
Шаг 4: обмен кода на токены
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_…"}
scopeперечисляет предоставленные разрешения. Сохраните их вместе с токенами и отобразите только те функции, которые они охватывают.patient— это идентификатор записи для вашего приложения. Он является парным: другое приложение видит того же человека под другим идентификатором.id_token— это токен OpenID Connect, полеfhirUserкоторого содержит имя ресурса пациента.- Код работает один раз и только с соответствующим
code_verifier.
Шаг 5: вызов API в рамках разрешений
curl "https://platform.anpheros.com/fhir/R4/Observation?patient=$PATIENT&category=laboratory" -H "Authorization: Bearer $ACCESS_TOKEN"
Результаты лабораторных исследований возвращаются как обычно. Запросите что-то, выходящее за рамки предоставленных разрешений, например, лекарства:
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."}]}
Это 403. Поиски в рамках разрешений также фильтруются: с Observation.rs?category=laboratory поиск всех наблюдений возвращает только лабораторные. Любой другой пациент не существует для этого токена (404). REST-представление (/v1) и контекстный API применяют те же разрешения.
Шаг 6: обновление
Токены доступа действительны в течение 30 минут. Токены обновления действительны в течение 30 дней и ротируются при каждом использовании:
curl -X POST https://platform.anpheros.com/oauth/token \
-d grant_type=refresh_token -d client_id=client_Hg6CknNkYlMgN190 -d refresh_token=$REFRESH_TOKEN
Вы получаете новый токен доступа и новый токен обновления. Сохраните новый немедленно. Повторное использование старого токена обновления рассматривается как кража: оно завершается ошибкой 400 и отзывает весь грант.
Шаг 7: Отзыв доступа
Пользователь может отозвать ваш доступ из Anpheros в любое время, и вы также можете отозвать его самостоятельно, например, когда пользователь отключается в вашем приложении:
curl -X POST https://platform.anpheros.com/oauth/revoke -d token=$REFRESH_TOKEN -d client_id=client_Hg6CknNkYlMgN190
С этого момента каждый вызов с использованием этого grant будет отвечать 401. Обработайте это, показав пользователю, что соединение завершено, и предложив подключиться снова. Подпишитесь на вебхук consent.revoked, чтобы узнать об этом, не дожидаясь неудачного вызова.
С помощью SDK
TypeScript и Dart SDK выполняют шаги с 3 по 6 за вас: OAuthFlow.authorizeUrl с сгенерированной парой PKCE, exchange при обратном вызове и автоматическое обновление с ротацией. Полные примеры: Как создать приложение для здравоохранения с ИИ и бэкендом FHIR (TypeScript) и Как создать приложение для здравоохранения с Flutter (Dart).
Что реализует Anpheros
| Часть SMART | В Anpheros |
|---|---|
| Discovery | /.well-known/smart-configuration на базе FHIR, с поддерживаемыми конечными точками, областями действия (scopes) и методами PKCE |
| Launch | автономный запуск (приложение запускается, затем запрашивает доступ); запуск из EHR в рамках клинической системы не предлагается |
| Authorisation | OAuth 2.1 с обязательным PKCE, поток кода авторизации |
| Scopes | пациентские области действия SMART v2, patient/<Resource>.<cruds> с фильтрами по категориям, а также openid и fhirUser |
| Identity | OpenID Connect id_token, называющий пациента как ресурс FHIR |
| Consent | размещенный экран согласия на языке пациента, с продолжительностью, выбранной пациентом, отраженный как FHIR Consent |
| Tokens | 30-минутные токены доступа, ротируемые 30-дневные токены обновления, привязанные к согласию, отзыв |
| Conformance | заявление о возможностях объявляет службу безопасности SMART; группа "Standalone Launch" набора тестов Inferno SMART App Launch STU2 проходит 22 из 22 тестов (запуск от 28 сентября 2026 г.); другие группы и наборы тестов Inferno не запускались |
Запись работает так же: запись областей действия (patient/Observation.c, .u, .d) позволяет вашему приложению создавать, обновлять или удалять данные в записи. Все, что записано, несет ваше приложение как автора, повторные попытки с ключом идемпотентности никогда не дублируют измерение, а удаления являются мягкими и сохраняют историю (Medical data API).
Чего еще нет
- Запуск из EHR (приложение, открываемое из внутренней системы больницы с контекстом запуска).
system/областей действия (scopes) для серверных служб; организации используют вместо них API-ключи.- Экспорт больших объемов данных (
$export); экспорт$everythingпо пациенту доступен.
Эти пункты перечислены вместе с остальными в разделе Версионирование и устаревание, а заявление о возможностях (capability statement) всегда является авторитетным источником.
Часто задаваемые вопросы
Что такое SMART on FHIR?
Открытый стандарт, основанный на OAuth 2.0/2.1 и OpenID Connect, который определяет, как приложение запрашивает доступ к записи FHIR, какие области действия описывают этот доступ и как сервер объявляет свои конечные точки. Любая клиентская библиотека с поддержкой SMART может использовать любой сервер с поддержкой SMART.
Нужен ли мне PKCE?
Да. Anpheros требует PKCE с S256 для каждого потока кода авторизации, как для публичных, так и для конфиденциальных клиентов. Это предотвращает использование перехваченного кода авторизации кем-либо другим.
Что произойдет, если пользователь откажет?
Пользователь вернется на ваш URI перенаправления с error=access_denied и вашим state, но без кода. Объясните, что требуется для этой функции, и позвольте пользователю попробовать снова; вызовы вне предоставленного разрешения всегда возвращают 403.
Может ли родитель дать согласие за ребенка?
Да. На экране согласия пользователь может выбрать запись, о которой он заботится, например, запись ребенка, если она связана с его учетной записью. Предоставленное разрешение применяется только к этой записи.
Связанные материалы
- Аутентификация и OAuth: API-ключи, токены и время их действия подробно
- API для здравоохранения с согласием пациента: как согласие влияет на дизайн вашего приложения
- Модель согласия и доступа
- Платформа FHIR
- Создание приложения для здравоохранения
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card