AnpherosAnpheros PlatformDevelopers

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:

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_…"}

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

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

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