Skip to content

Instantly share code, notes, and snippets.

@hansenms
Created November 22, 2018 13:52
Show Gist options
  • Save hansenms/088aadc9ebea38760af21841f73b2790 to your computer and use it in GitHub Desktop.
Save hansenms/088aadc9ebea38760af21841f73b2790 to your computer and use it in GitHub Desktop.

SMART on FHIR EHR Launch

This document captures the launch sequence from the SMART on FHIR sandbox for en EHR launch.

After retriving the /metadata contents, the client initiates the authorization:

GET https://launch.smarthealthit.org/v/r3/auth/authorize?client_id=whatever&response_type=code&scope=patient%2F*.*%20user%2F*.*%20launch%20openid%20profile%20offline_access&redirect_uri=https%3A%2F%2Flaunch.smarthealthit.org%2Fsample-app%2F&state=4e279d50-8a8f-be82-2803-c7136fdb4ff3&aud=&launch=eyJhIjoiMSIsImYiOiIxIn0&provider=smart-Practitioner-71482713&login_type=provider&aud_validated=1&login_success=1&patient=b2536dd3-bccd-4d22-8355-ab20acdf240b&select_first=true&encounter=e3ec2d15-4c27-4607-a45c-2f84962b0700

Note that patient, encounter, provider are passed as URL parameters to /authorize

The code is then returned:

GET https://launch.smarthealthit.org/sample-app/?code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb250ZXh0Ijp7Im5lZWRfcGF0aWVudF9iYW5uZXIiOmZhbHNlLCJzbWFydF9zdHlsZV91cmwiOiJodHRwczovL2xhdW5jaC5zbWFydGhlYWx0aGl0Lm9yZy9zbWFydC1zdHlsZS5qc29uIiwicGF0aWVudCI6ImIyNTM2ZGQzLWJjY2QtNGQyMi04MzU1LWFiMjBhY2RmMjQwYiIsImVuY291bnRlciI6ImUzZWMyZDE1LTRjMjctNDYwNy1hNDVjLTJmODQ5NjJiMDcwMCJ9LCJjbGllbnRfaWQiOiJ3aGF0ZXZlciIsInNjb3BlIjoicGF0aWVudC8qLiogdXNlci8qLiogbGF1bmNoIG9wZW5pZCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIiwidXNlciI6IlByYWN0aXRpb25lci9zbWFydC1QcmFjdGl0aW9uZXItNzE0ODI3MTMiLCJpYXQiOjE1NDI4OTI3MTMsImV4cCI6MTU0Mjg5MzAxM30.gmnZofjX7rxIrguroUJw4UgJr8xXVdfDXvKCbXfM2q8&state=4e279d50-8a8f-be82-2803-c7136fdb4ff3

Note that the code itself is a JWT. The contents of this token is:

{
  "context": {
    "need_patient_banner": false,
    "smart_style_url": "https://launch.smarthealthit.org/smart-style.json",
    "patient": "b2536dd3-bccd-4d22-8355-ab20acdf240b",
    "encounter": "e3ec2d15-4c27-4607-a45c-2f84962b0700"
  },
  "client_id": "whatever",
  "scope": "patient/*.* user/*.* launch openid profile offline_access",
  "user": "Practitioner/smart-Practitioner-71482713",
  "iat": 1542892713,
  "exp": 1542893013
}

So the code is now being used to transport the patient, encounter, etc.

Finally a token is obtained with:

POST https://launch.smarthealthit.org/v/r3/auth/token

The request body of the message is:

   client_id: whatever
   code: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb250ZXh0Ijp7Im5lZWRfcGF0aWVudF9iYW5uZXIiOmZhbHNlLCJzbWFydF9zdHlsZV91cmwiOiJodHRwczovL2xhdW5jaC5zbWFydGhlYWx0aGl0Lm9yZy9zbWFydC1zdHlsZS5qc29uIiwicGF0aWVudCI6ImIyNTM2ZGQzLWJjY2QtNGQyMi04MzU1LWFiMjBhY2RmMjQwYiIsImVuY291bnRlciI6ImUzZWMyZDE1LTRjMjctNDYwNy1hNDVjLTJmODQ5NjJiMDcwMCJ9LCJjbGllbnRfaWQiOiJ3aGF0ZXZlciIsInNjb3BlIjoicGF0aWVudC8qLiogdXNlci8qLiogbGF1bmNoIG9wZW5pZCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIiwidXNlciI6IlByYWN0aXRpb25lci9zbWFydC1QcmFjdGl0aW9uZXItNzE0ODI3MTMiLCJpYXQiOjE1NDI4OTI3MTMsImV4cCI6MTU0Mjg5MzAxM30.gmnZofjX7rxIrguroUJw4UgJr8xXVdfDXvKCbXfM2q8
   grant_type: authorization_code
   redirect_uri: https%3A%2F%2Flaunch.smarthealthit.org%2Fsample-app%2F

And finally the token response:

{
    "need_patient_banner": false,
    "smart_style_url": "https://launch.smarthealthit.org/smart-style.json",
    "patient": "b2536dd3-bccd-4d22-8355-ab20acdf240b",
    "encounter": "e3ec2d15-4c27-4607-a45c-2f84962b0700",
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb250ZXh0Ijp7Im5lZWRfcGF0aWVudF9iYW5uZXIiOmZhbHNlLCJzbWFydF9zdHlsZV91cmwiOiJodHRwczovL2xhdW5jaC5zbWFydGhlYWx0aGl0Lm9yZy9zbWFydC1zdHlsZS5qc29uIiwicGF0aWVudCI6ImIyNTM2ZGQzLWJjY2QtNGQyMi04MzU1LWFiMjBhY2RmMjQwYiIsImVuY291bnRlciI6ImUzZWMyZDE1LTRjMjctNDYwNy1hNDVjLTJmODQ5NjJiMDcwMCJ9LCJjbGllbnRfaWQiOiJ3aGF0ZXZlciIsInNjb3BlIjoicGF0aWVudC8qLiogdXNlci8qLiogbGF1bmNoIG9wZW5pZCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIiwidXNlciI6IlByYWN0aXRpb25lci9zbWFydC1QcmFjdGl0aW9uZXItNzE0ODI3MTMiLCJpYXQiOjE1NDI4OTI3MTMsImV4cCI6MTU3NDQyODcxNn0.57HMcZf5vHwCceZM2UZRiUhWBxplN_Ytr3frX-q-4Q0",
    "token_type": "bearer",
    "scope": "patient/*.* user/*.* launch openid profile offline_access",
    "client_id": "whatever",
    "expires_in": 3600,
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJwcm9maWxlIjoiUHJhY3RpdGlvbmVyL3NtYXJ0LVByYWN0aXRpb25lci03MTQ4MjcxMyIsImF1ZCI6IndoYXRldmVyIiwic3ViIjoiZGIyM2QwZGUyNTY3OGU2NzA5OWJjNDM0MzIzZGMwZDk2NTEzYjU1MjJkNGI3NDFjYmEzOWY3YzkyZDBjNDZhZSIsImlzcyI6Imh0dHBzOi8vbGF1bmNoLnNtYXJ0aGVhbHRoaXQub3JnIiwiaWF0IjoxNTQyODkyNzE2LCJleHAiOjE1NDI4OTYzMTZ9.4Ehr5amtWKoHf0HCooo99oMb9qBMl99aT129lp49tZF4RTWD8WhJaNZClYNJCdVNl-_-cwSAC8h_1ourtDJCPCiGH8-CUT2O2C1PcueuGU_3pvMiOQDAxRi-zaGRSEQDDpeydUPUwKd5bNXJyO4hDEsQpRS1bAW-OQ2J1KkjWFCdjvpQI0Tvf7uESLlXNqMUHwSCyCOBrTjkUF6NYVc67gVuA72zZPFIUfFRz6SzTtzK3VpwrevJ4QgP10Dx9r-j_dF8G89elZU_1DeyUKRLQAo1ZPGhYFR7zG4mdcEmVZHS1G9pERNjlfPYKSFyFoMrY7fQJsWBSAYkyzQC-wezHA",
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZWVkX3BhdGllbnRfYmFubmVyIjpmYWxzZSwic21hcnRfc3R5bGVfdXJsIjoiaHR0cHM6Ly9sYXVuY2guc21hcnRoZWFsdGhpdC5vcmcvc21hcnQtc3R5bGUuanNvbiIsInBhdGllbnQiOiJiMjUzNmRkMy1iY2NkLTRkMjItODM1NS1hYjIwYWNkZjI0MGIiLCJlbmNvdW50ZXIiOiJlM2VjMmQxNS00YzI3LTQ2MDctYTQ1Yy0yZjg0OTYyYjA3MDAiLCJyZWZyZXNoX3Rva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SmpiMjUwWlhoMElqcDdJbTVsWldSZmNHRjBhV1Z1ZEY5aVlXNXVaWElpT21aaGJITmxMQ0p6YldGeWRGOXpkSGxzWlY5MWNtd2lPaUpvZEhSd2N6b3ZMMnhoZFc1amFDNXpiV0Z5ZEdobFlXeDBhR2wwTG05eVp5OXpiV0Z5ZEMxemRIbHNaUzVxYzI5dUlpd2ljR0YwYVdWdWRDSTZJbUl5TlRNMlpHUXpMV0pqWTJRdE5HUXlNaTA0TXpVMUxXRmlNakJoWTJSbU1qUXdZaUlzSW1WdVkyOTFiblJsY2lJNkltVXpaV015WkRFMUxUUmpNamN0TkRZd055MWhORFZqTFRKbU9EUTVOakppTURjd01DSjlMQ0pqYkdsbGJuUmZhV1FpT2lKM2FHRjBaWFpsY2lJc0luTmpiM0JsSWpvaWNHRjBhV1Z1ZEM4cUxpb2dkWE5sY2k4cUxpb2diR0YxYm1Ob0lHOXdaVzVwWkNCd2NtOW1hV3hsSUc5bVpteHBibVZmWVdOalpYTnpJaXdpZFhObGNpSTZJbEJ5WVdOMGFYUnBiMjVsY2k5emJXRnlkQzFRY21GamRHbDBhVzl1WlhJdE56RTBPREkzTVRNaUxDSnBZWFFpT2pFMU5ESTRPVEkzTVRNc0ltVjRjQ0k2TVRVM05EUXlPRGN4Tm4wLjU3SE1jWmY1dkh3Q2NlWk0yVVpSaVVoV0J4cGxOX1l0cjNmclgtcS00UTAiLCJ0b2tlbl90eXBlIjoiYmVhcmVyIiwic2NvcGUiOiJwYXRpZW50LyouKiB1c2VyLyouKiBsYXVuY2ggb3BlbmlkIHByb2ZpbGUgb2ZmbGluZV9hY2Nlc3MiLCJjbGllbnRfaWQiOiJ3aGF0ZXZlciIsImV4cGlyZXNfaW4iOjM2MDAsImlkX3Rva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SndjbTltYVd4bElqb2lVSEpoWTNScGRHbHZibVZ5TDNOdFlYSjBMVkJ5WVdOMGFYUnBiMjVsY2kwM01UUTRNamN4TXlJc0ltRjFaQ0k2SW5kb1lYUmxkbVZ5SWl3aWMzVmlJam9pWkdJeU0yUXdaR1V5TlRZM09HVTJOekE1T1dKak5ETTBNekl6WkdNd1pEazJOVEV6WWpVMU1qSmtOR0kzTkRGalltRXpPV1kzWXpreVpEQmpORFpoWlNJc0ltbHpjeUk2SW1oMGRIQnpPaTh2YkdGMWJtTm9Mbk50WVhKMGFHVmhiSFJvYVhRdWIzSm5JaXdpYVdGMElqb3hOVFF5T0RreU56RTJMQ0psZUhBaU9qRTFOREk0T1RZek1UWjkuNEVocjVhbXRXS29IZjBIQ29vbzk5b01iOXFCTWw5OWFUMTI5bHA0OXRaRjRSVFdEOFdoSmFOWkNsWU5KQ2RWTmwtXy1jd1NBQzhoXzFvdXJ0REpDUENpR0g4LUNVVDJPMkMxUGN1ZXVHVV8zcHZNaU9RREF4UmktemFHUlNFUUREcGV5ZFVQVXdLZDViTlhKeU80aERFc1FwUlMxYkFXLU9RMkoxS2tqV0ZDZGp2cFFJMFR2Zjd1RVNMbFhOcU1VSHdTQ3lDT0JyVGprVUY2TllWYzY3Z1Z1QTcyelpQRklVZkZSejZTelR0ekszVnB3cmV2SjRRZ1AxMER4OXItal9kRjhHODllbFpVXzFEZXlVS1JMUUFvMVpQR2hZRlI3ekc0bWRjRW1WWkhTMUc5cEVSTmpsZlBZS1NGeUZvTXJZN2ZRSnNXQlNBWWt5elFDLXdlekhBIiwiaWF0IjoxNTQyODkyNzE2LCJleHAiOjE1NDI4OTYzMTZ9.CMKpypl2DDDM55w2-JovhuPdGryrmrSzWvhT58ntk8Q"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment