Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Cómo implementar el consentimiento del paciente con SMART on FHIR
Tutorial: SMART on FHIR con OAuth 2.1 y PKCE paso a paso — descubrimiento, registro de app, pantalla de consentimiento, intercambio de tokens, ámbitos aplicados, rotación de refresco y revocación — y qué implementa Anpheros.
SMART on FHIR es la forma estándar en que una aplicación obtiene el permiso de una persona para acceder a su registro FHIR: OAuth 2.1 con PKCE para la autorización, ámbitos que indican exactamente qué se puede leer o escribir, y un documento de descubrimiento que indica a la aplicación a dónde ir. Este tutorial ejecuta todo el flujo contra Anpheros, paso a paso con curl: descubrimiento, registro de una aplicación, envío de la persona a la pantalla de consentimiento, intercambio del código, llamada a la API dentro de los ámbitos concedidos, refresco y lo que sucede cuando la persona revoca el acceso. Anpheros es el backend de SMART on FHIR: aloja el servidor de autorización, la pantalla de consentimiento y el servidor FHIR R4, por lo que usted no escribe ninguna interfaz de usuario de inicio de sesión o consentimiento propia.
Por qué consentimiento y no solo una clave de API
Una clave de API llega a los pacientes que creó su proyecto. El registro existente de una persona (sus propios datos, recopilados por otras aplicaciones, clínicas y laboratorios) es suyo para compartir. Con SMART on FHIR:
- la persona ve, en su idioma, qué aplicación solicita, qué quiere leer o escribir, con qué propósito y por cuánto tiempo;
- su aplicación obtiene solo esos tipos de recursos y acciones, y solo para ese registro;
- cada acceso se registra y es visible para la persona, quien puede revocarlo en cualquier momento;
- la concesión también se almacena como un recurso FHIR
Consent.
El modelo detrás de esto se describe en API de salud con consentimiento del paciente y Modelo de consentimiento y acceso.
Paso 1: descubrimiento
curl https://platform.anpheros.com/fhir/R4/.well-known/smart-configuration
La respuesta enumera los puntos finales y lo que el servidor soporta (abreviado):
{"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"]}
Las bibliotecas cliente de SMART leen este documento y no necesitan ninguna configuración adicional.
Paso 2: registrar su aplicación
En el panel, abra su proyecto y agregue una aplicación con su URI de redireccionamiento. O a través de la API de administración:
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", …}
Use public para aplicaciones móviles y de navegador, que no pueden mantener un secreto y dependen de PKCE. Use confidential para un servidor; su client_secret se muestra una vez. El nombre, el propósito y el enlace de privacidad son lo que la persona ve en la pantalla de consentimiento.
Paso 3: enviar a la persona a la pantalla de consentimiento
Crea un par PKCE. El verificador se queda contigo; solo su hash viaja:
VERIFIER=$(openssl rand -base64 64 | tr -d '=+/\n' | cut -c1-64)
CHALLENGE=$(printf %s "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
Luego abre esta dirección en el navegador de la persona (se agregaron saltos de línea para facilitar la lectura):
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
Pide lo mínimo que necesitas. Esta aplicación lee resultados de laboratorio y diagnósticos, nada más. offline_access otorga un token de actualización, para que la persona no tenga que aprobar nuevamente cada 30 minutos.
La persona inicia sesión en Anpheros, lee la solicitud en lenguaje claro, elige qué registro compartir (el suyo propio, el de un familiar que cuida, o el que tu aplicación creó para ellos) y cuánto tiempo dura el acceso, luego permite o deniega. Regresan a tu URI de redirección:
https://cardio.example/callback?code=…&state=8c1e…
Verifica que state sea el valor que enviaste antes de usar el código.
Paso 4: Intercambiar el código por tokens
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_…"}
scopelista lo que se concedió. Manténgalo con los tokens y muestre solo las características que cubre.patientes el id del registro para su aplicación. Es por pares: otra aplicación ve a la misma persona bajo un id diferente.id_tokenes un token de OpenID Connect cuyo claimfhirUsernombra el recurso del paciente.- El código funciona una vez, y solo con el
code_verifiercorrespondiente.
Paso 5: llamar a la API dentro de los ámbitos
curl "https://platform.anpheros.com/fhir/R4/Observation?patient=$PATIENT&category=laboratory" -H "Authorization: Bearer $ACCESS_TOKEN"
Los resultados de laboratorio vuelven como de costumbre. Solicite algo fuera de la concesión, como medicamentos:
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."}]}
Eso es un 403. Las búsquedas dentro de la concesión también se filtran: con Observation.rs?category=laboratory, una búsqueda de todas las observaciones devuelve solo las de laboratorio. Cualquier otro paciente no existe para este token (404). La vista REST (/v1) y la API de contexto aplican los mismos ámbitos.
Paso 6: Actualizar
Los tokens de acceso duran 30 minutos. Los tokens de actualización duran 30 días y rotan en cada uso:
curl -X POST https://platform.anpheros.com/oauth/token \
-d grant_type=refresh_token -d client_id=client_Hg6CknNkYlMgN190 -d refresh_token=$REFRESH_TOKEN
Obtienes un nuevo token de acceso y un nuevo token de actualización. Almacena el nuevo inmediatamente. Reutilizar un token de actualización antiguo se considera un robo: falla con 400 y revoca toda la concesión.
Paso 7: revocación
La persona puede revocar tu acceso desde Anpheros en cualquier momento, y tú puedes revocarlo tú mismo, por ejemplo, cuando se desconecten en tu aplicación:
curl -X POST https://platform.anpheros.com/oauth/revoke -d token=$REFRESH_TOKEN -d client_id=client_Hg6CknNkYlMgN190
A partir de entonces, cada llamada con esa concesión responderá 401. Maneja esto mostrando a la persona que la conexión ha finalizado y ofreciendo volver a conectar. Suscríbete al webhook consent.revoked para enterarte sin esperar una llamada fallida.
Con los SDKs
Los SDKs de TypeScript y Dart realizan los pasos 3 a 6 por usted: OAuthFlow.authorizeUrl con un par PKCE generado, exchange en el callback, y refresco automático con rotación. Ejemplos completos: Cómo crear una aplicación de salud con IA con un backend FHIR (TypeScript) y Cómo crear una aplicación de salud con Flutter (Dart).
Lo que implementa Anpheros
| Parte de SMART | En Anpheros |
|---|---|
| Descubrimiento | /.well-known/smart-configuration en la base FHIR, con los endpoints, scopes y métodos PKCE soportados |
| Lanzamiento | lanzamiento independiente (la aplicación se inicia y luego solicita acceso); no se ofrece lanzamiento desde EHR dentro de un sistema clínico |
| Autorización | OAuth 2.1 con PKCE requerido, flujo de código de autorización |
| Scopes | scopes de paciente SMART v2, patient/<Resource>.<cruds> con filtros de categoría, además de openid y fhirUser |
| Identidad | un OpenID Connect id_token que nombra al paciente como un recurso FHIR |
| Consentimiento | una pantalla de consentimiento alojada en el idioma del paciente, con la duración elegida por el paciente, reflejada como un Consent FHIR |
| Tokens | tokens de acceso de 30 minutos, tokens de actualización rotativos de 30 días vinculados al consentimiento, revocación |
| Conformidad | la declaración de capacidad declara el servicio de seguridad SMART; el grupo "Standalone Launch" del kit de pruebas Inferno SMART App Launch STU2 pasa 22 de 22 pruebas (ejecución del 28 de septiembre de 2026); los otros grupos y kits de pruebas de Inferno no se han ejecutado |
La escritura funciona de la misma manera: escribir scopes (patient/Observation.c, .u, .d) permite a su aplicación crear, actualizar o eliminar dentro del registro. Todo lo escrito lleva su aplicación como autor, los reintentos con una clave de idempotencia nunca duplican una medición, y las eliminaciones son blandas y conservan el historial (Medical data API).
Lo que aún no está disponible
- Lanzamiento desde EHR (la aplicación se abre desde dentro de un sistema hospitalario con un contexto de lanzamiento).
system/ámbitos para servicios backend; las organizaciones utilizan claves API en su lugar.- Exportación de datos masivos (
$export);$everythingsobre un paciente está disponible.
Estos se enumeran con el resto en Versionamiento y deprecación, y la declaración de capacidad es siempre la fuente autorizada.
Preguntas frecuentes
¿Qué es SMART on FHIR?
Un estándar abierto, basado en OAuth 2.0/2.1 y OpenID Connect, que define cómo una aplicación solicita acceso a un registro FHIR, qué ámbitos describen ese acceso y cómo el servidor anuncia sus puntos de conexión. Cualquier biblioteca cliente compatible con SMART puede utilizar cualquier servidor compatible con SMART.
¿Necesito PKCE?
Sí. Anpheros requiere PKCE con S256 para cada flujo de código de autorización, tanto para clientes públicos como confidenciales. Evita que un código de autorización interceptado sea utilizado por cualquier otra persona.
¿Qué sucede si la persona dice que no?
Regresan a su URI de redirección con error=access_denied y su state, y sin código. Explique lo que necesita la función y permítales intentarlo de nuevo; las llamadas fuera de una concesión siempre responden 403.
¿Puede un padre dar consentimiento para un hijo?
Sí. En la pantalla de consentimiento, una persona puede elegir un registro que le interese, como el de un hijo, si está vinculado a su cuenta. La concesión se aplica solo a ese registro.
Relacionado
- Autenticación y OAuth: claves API, tokens y duraciones en detalle
- API de salud con consentimiento del paciente: cómo el consentimiento cambia el diseño de su aplicación
- Modelo de consentimiento y acceso
- Plataforma FHIR
- Crear una aplicación de salud
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card