Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Como implementar o consentimento do paciente com SMART on FHIR
Tutorial: SMART on FHIR com OAuth 2.1 e PKCE passo a passo — descoberta, registo da app, ecrã de consentimento, troca de tokens, âmbitos aplicados, rotação de refresh e revogação — e o que o Anpheros implementa.
SMART on FHIR é a forma padrão de uma aplicação obter a permissão de uma pessoa para aceder ao seu registo FHIR: OAuth 2.1 com PKCE para a autorização, escopos que indicam exatamente o que pode ser lido ou escrito, e um documento de descoberta que informa a aplicação para onde ir. Este tutorial executa todo o fluxo contra a Anpheros, passo a passo com curl: descoberta, registo de uma aplicação, envio da pessoa para o ecrã de consentimento, troca do código, chamada da API dentro dos escopos concedidos, refresh, e o que acontece quando a pessoa revoga o acesso. A Anpheros é o backend SMART on FHIR: hospeda o servidor de autorização, o ecrã de consentimento e o servidor FHIR R4, pelo que não escreve nenhuma UI de login ou consentimento própria.
Porquê consentimento e não apenas uma chave de API
Uma chave de API alcança os pacientes que o seu projeto criou. O registo existente de uma pessoa (os seus próprios dados, recolhidos por outras aplicações, clínicas e laboratórios) é seu para partilhar. Com SMART on FHIR:
- a pessoa vê, na sua língua, qual a aplicação que pergunta, o que pretende ler ou escrever, para que finalidade e por quanto tempo;
- a sua aplicação obtém apenas esses tipos de recursos e ações, e apenas para esse registo específico;
- cada acesso é registado e visível para a pessoa, que o pode revogar a qualquer momento;
- a concessão é também armazenada como um recurso FHIR
Consent.
O modelo subjacente é descrito em Healthcare API with patient consent e Consent and access model.
Passo 1: Descoberta
curl https://platform.anpheros.com/fhir/R4/.well-known/smart-configuration
A resposta lista os endpoints e o que o servidor suporta (resumido):
{"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"]}
As bibliotecas cliente SMART leem este documento e não necessitam de mais nenhuma configuração.
Passo 2: registar a sua aplicação
No painel de controlo, abra o seu projeto e adicione uma aplicação com o seu URI de redirecionamento. Ou através da API de Administração:
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", …}
Utilize public para aplicações móveis e de navegador, que não podem manter um segredo e dependem de PKCE. Utilize confidential para um servidor; o seu client_secret é mostrado uma vez. O nome, propósito e link de privacidade são o que a pessoa vê no ecrã de consentimento.
Passo 3: Enviar a pessoa para o ecrã de consentimento
Crie um par PKCE. O verificador fica consigo; apenas o seu hash é enviado:
VERIFIER=$(openssl rand -base64 64 | tr -d '=+/\n' | cut -c1-64)
CHALLENGE=$(printf %s "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
Em seguida, abra este endereço no navegador da pessoa (quebras de linha adicionadas para leitura):
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
Peça o mínimo de que necessita. Esta aplicação lê resultados de laboratório e diagnósticos, nada mais. offline_access fornece um token de atualização, para que a pessoa não tenha de aprovar novamente a cada 30 minutos.
A pessoa inicia sessão no Anpheros, lê o pedido em linguagem clara, escolhe qual registo partilhar (o seu próprio, o de um membro da família de quem cuida, ou o que a sua aplicação criou para si) e por quanto tempo o acesso dura, e depois permite ou nega. Regressa ao seu URI de redirecionamento:
https://cardio.example/callback?code=…&state=8c1e…
Verifique se state é o valor que enviou antes de usar o código.
Passo 4: Trocar o 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 o que foi concedido. Mantenha-o com os tokens e mostre apenas as funcionalidades que cobre.patienté o ID do registo para a sua aplicação. É par: outra aplicação vê a mesma pessoa sob um ID diferente.id_tokené um token OpenID Connect cujo claimfhirUsernomeia o recurso do paciente.- O código funciona uma vez, e apenas com o
code_verifiercorrespondente.
Passo 5: chamar a API dentro dos escopos
curl "https://platform.anpheros.com/fhir/R4/Observation?patient=$PATIENT&category=laboratory" -H "Authorization: Bearer $ACCESS_TOKEN"
Os resultados de laboratório retornam como habitual. Peça algo fora da concessão, 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."}]}
Isso é um 403. As pesquisas dentro da concessão também são filtradas: com Observation.rs?category=laboratory, uma pesquisa por todas as observações retorna apenas as de laboratório. Qualquer outro paciente não existe para este token (404). A vista REST (/v1) e a API de contexto aplicam os mesmos escopos.
Passo 6: refresh
Os tokens de acesso duram 30 minutos. Os tokens de refresh duram 30 dias e rodam a cada utilização:
curl -X POST https://platform.anpheros.com/oauth/token \
-d grant_type=refresh_token -d client_id=client_Hg6CknNkYlMgN190 -d refresh_token=$REFRESH_TOKEN
Recebe um novo token de acesso e um novo token de refresh. Armazene o novo imediatamente. A reutilização de um token de refresh antigo é tratada como roubo: falha com 400 e revoga toda a concessão.
Passo 7: revogação
A pessoa pode revogar o seu acesso a partir do Anpheros a qualquer momento, e pode revogá-lo você mesmo, por exemplo, quando ela se desconecta na sua aplicação:
curl -X POST https://platform.anpheros.com/oauth/revoke -d token=$REFRESH_TOKEN -d client_id=client_Hg6CknNkYlMgN190
A partir daí, todas as chamadas com essa concessão falham 401. Lide com isso mostrando à pessoa que a ligação terminou e oferecendo-se para ligar novamente. Subscreva o webhook consent.revoked para saber sem ter de esperar por uma chamada falhada.
Com os SDKs
Os SDKs TypeScript e Dart realizam os passos 3 a 6 por si: OAuthFlow.authorizeUrl com um par PKCE gerado, exchange no callback, e refresh automático com rotação. Exemplos completos: Como criar uma app de saúde com IA e um backend FHIR (TypeScript) e Como criar uma app de saúde com Flutter (Dart).
O que o Anpheros implementa
| Parte do SMART | No Anpheros |
|---|---|
| Discovery | /.well-known/smart-configuration na base FHIR, com os endpoints, scopes e métodos PKCE suportados |
| Launch | launch standalone (a aplicação inicia, depois pede acesso); launch EHR a partir de um sistema clínico não é oferecido |
| Autorização | OAuth 2.1 com PKCE obrigatório, fluxo de código de autorização |
| Scopes | scopes de paciente SMART v2, patient/<Resource>.<cruds> com filtros de categoria, mais openid e fhirUser |
| Identidade | um OpenID Connect id_token nomeando o paciente como um recurso FHIR |
| Consentimento | um ecrã de consentimento hospedado na língua do paciente, com a duração escolhida pelo paciente, espelhado como um FHIR Consent |
| Tokens | tokens de acesso de 30 minutos, tokens de refresh rotativos de 30 dias vinculados ao consentimento, revogação |
| Conformance | a declaração de capacidade declara o serviço de segurança SMART; o grupo "Standalone Launch" do kit de teste Inferno SMART App Launch STU2 passa 22 de 22 testes (execução de 28 de setembro de 2026); os outros grupos e kits de teste Inferno não foram executados |
A escrita funciona da mesma forma: escrever scopes (patient/Observation.c, .u, .d) permite que a sua aplicação crie, atualize ou elimine dentro do registo. Tudo o que é escrito carrega a sua aplicação como autor, retentativas com uma chave de idempotência nunca duplicam uma medição, e as eliminações são suaves e mantêm o histórico (Medical data API).
O que ainda não existe
- Lançamento EHR (a aplicação aberta a partir de um sistema hospitalar com um contexto de lançamento).
system/escopos para serviços de backend; as organizações usam chaves de API em vez disso.- Exportação de dados em massa (
$export);$everythingnum paciente está disponível.
Estes são listados com o resto em Versioning and deprecation, e a declaração de capacidade é sempre a fonte autoritativa.
Perguntas frequentes
O que é SMART on FHIR?
Um padrão aberto, construído sobre OAuth 2.0/2.1 e OpenID Connect, que define como uma aplicação solicita acesso a um registo FHIR, quais os âmbitos (scopes) que descrevem esse acesso e como o servidor anuncia os seus pontos de extremidade (endpoints). Qualquer biblioteca cliente compatível com SMART pode usar qualquer servidor compatível com SMART.
Preciso de PKCE?
Sim. O Anpheros requer PKCE com S256 para todos os fluxos de código de autorização, tanto para clientes públicos como confidenciais. Impede que um código de autorização intercetado seja utilizado por qualquer outra pessoa.
O que acontece se a pessoa disser não?
Regressam ao seu URI de redirecionamento com error=access_denied e o seu state, e sem código. Explique o que a funcionalidade necessita e deixe-os tentar novamente; chamadas fora de uma concessão (grant) respondem sempre com 403.
Um progenitor pode dar consentimento para um filho?
Sim. No ecrã de consentimento, uma pessoa pode escolher um registo de que cuida, como o de um filho, se este estiver associado à sua conta. A concessão (grant) aplica-se apenas a esse registo.
Relacionado
- Autenticação e OAuth: Chaves de API, tokens e tempos de vida em detalhe
- API de Saúde com consentimento do paciente: como o consentimento altera o design da sua aplicação
- Modelo de consentimento e acesso
- Plataforma FHIR
- Criar uma aplicação de saúde
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card