AnpherosAnpheros PlatformDevelopers

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 进行授权,使用作用域精确说明可读写的内容,以及使用发现文档告知应用程序去哪里。 本教程将分步演示整个流程在 Anpheros 上的运行情况,包括 curl:发现、注册应用程序、将用户引导至同意屏幕、交换代码、在授予的作用域内调用 API、刷新以及用户撤销访问时发生的情况。Anpheros 是 SMART on FHIR 后端:它托管授权服务器、同意屏幕和 FHIR R4 服务器,因此您无需编写自己的登录或同意 UI。

为什么使用同意书而不是 API 密钥

API 密钥只能访问您的项目创建的患者数据。个人的现有记录(他们自己的数据,由其他应用程序、诊所和实验室收集)由他们自己决定是否共享。使用 SMART on FHIR:

其背后的模型在 带有患者同意书的医疗保健 API 和 同意书和访问模型 中有详细描述。

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

对于无法保管密钥并依赖 PKCE 的移动和浏览器应用,请使用 public。对于服务器,请使用 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_…"}

步骤 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

从那时起,使用该授权的所有调用都将返回 401。通过向用户显示连接已结束并提供重新连接的选项来处理此情况。订阅 consent.revoked webhook 可以在不等待调用失败的情况下获知此信息。

使用 SDK

TypeScript 和 Dart SDK 会为您处理步骤 3 到 6:OAuthFlow.authorizeUrl 使用生成的 PKCE 对,exchange 在回调时,以及自动刷新和轮换。完整示例:如何使用 FHIR 后端构建 AI 医疗保健应用 (TypeScript) 和 如何使用 Flutter 构建医疗保健应用 (Dart)。

Anpheros 的实现

SMART 的部分 Anpheros 中的实现
Discovery /.well-known/smart-configuration on the FHIR base, with the endpoints, scopes and PKCE methods supported
Launch standalone launch (应用程序启动,然后请求访问);不支持从临床系统内部启动的 EHR launch
Authorisation OAuth 2.1 with PKCE required, authorisation code flow
Scopes SMART v2 patient scopes, patient/<Resource>.<cruds> with category filters, plus openid and fhirUser
Identity an OpenID Connect id_token naming the patient as a FHIR resource
Consent a hosted consent screen in the patient's language, with the duration chosen by the patient, mirrored as a FHIR Consent
Tokens 30-minute access tokens, rotating 30-day refresh tokens bound to the consent, revocation
Conformance the capability statement declares the SMART security service; the "Standalone Launch" group of the Inferno SMART App Launch STU2 test kit passes 22 of 22 tests (run of 28 September 2026); the other Inferno groups and test kits have not been run

Writing works the same way: write scopes (patient/Observation.c, .u, .d) let your application create, update or delete within the record. Everything written carries your application as the author, retries with an idempotency key never duplicate a measurement, and deletions are soft and keep history (Medical data API).

尚不支持的功能

这些功能与其余功能一起列在 版本控制和弃用 中,能力声明始终是权威来源。

常见问题解答

什么是 SMART on FHIR?

SMART on FHIR 是一个开放标准,基于 OAuth 2.0/2.1 和 OpenID Connect 构建,它定义了应用程序如何请求访问 FHIR 记录,哪些范围描述了该访问,以及服务器如何宣传其端点。任何支持 SMART 的客户端库都可以使用任何支持 SMART 的服务器。

我需要 PKCE 吗?

是的。Anpheros 要求对所有授权码流程都使用 PKCE 和 S256,无论是公共客户端还是机密客户端。这可以防止截获的授权码被其他人使用。

如果用户拒绝怎么办?

用户将返回到您的重定向 URI,并附带 error=access_denied 和您的 state,但没有代码。请解释该功能的需求,并让他们重试;在授权之外的调用始终会返回 403。

家长可以为孩子提供同意吗?

可以。在同意屏幕上,用户可以选择他们关心的记录,例如孩子的记录,前提是该记录已链接到他们的账户。授权仅适用于该记录。

相关资源

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Product updates by email

New features, guides and the end of the beta. One email a month at most.

Send me occasional Anpheros Platform updates by email (new features, API changes, guides). I'll confirm by email and can unsubscribe in one click from any email. Privacy