Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sween/7eb2b36de5a0a35c99f72be43824c93c to your computer and use it in GitHub Desktop.
Save sween/7eb2b36de5a0a35c99f72be43824c93c to your computer and use it in GitHub Desktop.
SMART on FHIR Standalone launch (patient)

First get `/metadata'

GET https://launch.smarthealthit.org/v/r3/sim/eyJrIjoiMSIsImIiOiJiMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQifQ/fhir/metadata

eyJrIjoiMSIsImIiOiJiMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQifQ is a JWT with the following header:

{
  "k": "1",
  "b": "b1f0365d-f405-45c0-8cbd-da56518e7504"
}

b1f0365d-f405-45c0-8cbd-da56518e7504 is the patient ID. Then launch the sim flow:

GET https://launch.smarthealthit.org/v/r3/sim/eyJrIjoiMSIsImIiOiJiMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQifQ/login?client_id=my_web_app&response_type=code&scope=openid%20profile%20offline_access%20user%2F*.*%20patient%2F*.*%20launch%2Fencounter%20launch%2Fpatient&redirect_uri=https%3A%2F%2Flaunch.smarthealthit.org%2Fsample-app%2F&state=3f15e92f-e501-c083-c160-9805c58f69bd&aud=&patient=b1f0365d-f405-45c0-8cbd-da56518e7504&login_type=patient&aud_validated=1

This brings up the login prompt for the patient and after signing in (but before accepting scopes), it does a search of Encounters:

GET https://launch.smarthealthit.org/v/r3/sim/eyJrIjoiMSIsImIiOiJiMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQifQ/fhir/Encounter/?_format=application/json+fhir&_count=1&patient=b1f0365d-f405-45c0-8cbd-da56518e7504&_sort:desc=date

Not clear where the authentication is coming from. The request has no Bearer token and should be rejected! So effectively, we are allowed to get the last Encounter for this patient prior to authenticating.

Then the actual auth flow starts.

GET https://launch.smarthealthit.org/v/r3/sim/eyJrIjoiMSIsImIiOiJiMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQifQ/authorize?client_id=my_web_app&response_type=code&scope=openid%20profile%20offline_access%20user%2F*.*%20patient%2F*.*%20launch%2Fencounter%20launch%2Fpatient&redirect_uri=https%3A%2F%2Flaunch.smarthealthit.org%2Fsample-app%2F&state=3f15e92f-e501-c083-c160-9805c58f69bd&aud=&patient=b1f0365d-f405-45c0-8cbd-da56518e7504&login_type=patient&aud_validated=1&login_success=1&select_first=true&encounter=35ba870a-df14-45ac-8bbf-16e9d6a0adf4

Notice that patient and encounter are authorization parameters. This bings up the consent dialog, if requested. Code comes back:

https://launch.smarthealthit.org/sample-app/?code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb250ZXh0Ijp7Im5lZWRfcGF0aWVudF9iYW5uZXIiOnRydWUsInNtYXJ0X3N0eWxlX3VybCI6Imh0dHBzOi8vbGF1bmNoLnNtYXJ0aGVhbHRoaXQub3JnL3NtYXJ0LXN0eWxlLmpzb24iLCJwYXRpZW50IjoiYjFmMDM2NWQtZjQwNS00NWMwLThjYmQtZGE1NjUxOGU3NTA0IiwiZW5jb3VudGVyIjoiMzViYTg3MGEtZGYxNC00NWFjLThiYmYtMTZlOWQ2YTBhZGY0In0sImNsaWVudF9pZCI6Im15X3dlYl9hcHAiLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIHVzZXIvKi4qIHBhdGllbnQvKi4qIGxhdW5jaC9lbmNvdW50ZXIgbGF1bmNoL3BhdGllbnQiLCJ1c2VyIjoiUGF0aWVudC9iMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQiLCJpYXQiOjE1NDMwMDA3MjYsImV4cCI6MTU0MzAwMTAyNn0.FT0V433Rgp3gK1AZ0tJtf4Db_ylGhfA3by6TY-7S4mY&state=3f15e92f-e501-c083-c160-9805c58f69bd```

The code is a JWT containing:

{
  "context": {
    "need_patient_banner": true,
    "smart_style_url": "https://launch.smarthealthit.org/smart-style.json",
    "patient": "b1f0365d-f405-45c0-8cbd-da56518e7504",
    "encounter": "35ba870a-df14-45ac-8bbf-16e9d6a0adf4"
  },
  "client_id": "my_web_app",
  "scope": "openid profile offline_access user/*.* patient/*.* launch/encounter launch/patient",
  "user": "Patient/b1f0365d-f405-45c0-8cbd-da56518e7504",
  "iat": 1543000726,
  "exp": 1543001026
}

A token is then requested:

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

Request body:

   client_id: my_web_app
   code: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb250ZXh0Ijp7Im5lZWRfcGF0aWVudF9iYW5uZXIiOnRydWUsInNtYXJ0X3N0eWxlX3VybCI6Imh0dHBzOi8vbGF1bmNoLnNtYXJ0aGVhbHRoaXQub3JnL3NtYXJ0LXN0eWxlLmpzb24iLCJwYXRpZW50IjoiYjFmMDM2NWQtZjQwNS00NWMwLThjYmQtZGE1NjUxOGU3NTA0IiwiZW5jb3VudGVyIjoiMzViYTg3MGEtZGYxNC00NWFjLThiYmYtMTZlOWQ2YTBhZGY0In0sImNsaWVudF9pZCI6Im15X3dlYl9hcHAiLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIHVzZXIvKi4qIHBhdGllbnQvKi4qIGxhdW5jaC9lbmNvdW50ZXIgbGF1bmNoL3BhdGllbnQiLCJ1c2VyIjoiUGF0aWVudC9iMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQiLCJpYXQiOjE1NDMwMDA3MjYsImV4cCI6MTU0MzAwMTAyNn0.FT0V433Rgp3gK1AZ0tJtf4Db_ylGhfA3by6TY-7S4mY
   grant_type: authorization_code
   redirect_uri: https%3A%2F%2Flaunch.smarthealthit.org%2Fsample-app%2F

And the token response:

{
   "need_patient_banner": true,
   "smart_style_url": "https://launch.smarthealthit.org/smart-style.json",
   "patient": "b1f0365d-f405-45c0-8cbd-da56518e7504",
   "encounter": "35ba870a-df14-45ac-8bbf-16e9d6a0adf4",
   "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb250ZXh0Ijp7Im5lZWRfcGF0aWVudF9iYW5uZXIiOnRydWUsInNtYXJ0X3N0eWxlX3VybCI6Imh0dHBzOi8vbGF1bmNoLnNtYXJ0aGVhbHRoaXQub3JnL3NtYXJ0LXN0eWxlLmpzb24iLCJwYXRpZW50IjoiYjFmMDM2NWQtZjQwNS00NWMwLThjYmQtZGE1NjUxOGU3NTA0IiwiZW5jb3VudGVyIjoiMzViYTg3MGEtZGYxNC00NWFjLThiYmYtMTZlOWQ2YTBhZGY0In0sImNsaWVudF9pZCI6Im15X3dlYl9hcHAiLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIHVzZXIvKi4qIHBhdGllbnQvKi4qIGxhdW5jaC9lbmNvdW50ZXIgbGF1bmNoL3BhdGllbnQiLCJ1c2VyIjoiUGF0aWVudC9iMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQiLCJpYXQiOjE1NDMwMDA3MjYsImV4cCI6MTU3NDUzNjcyOH0.0mNRgPnuEs0OGSKXmBXeQLD4u9QvPkCRBDuTw8Kz5rA",
   "token_type": "bearer",
   "scope": "openid profile offline_access user/*.* patient/*.* launch/encounter launch/patient",
   "client_id": "my_web_app",
   "expires_in": 3600,
   "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJwcm9maWxlIjoiUGF0aWVudC9iMWYwMzY1ZC1mNDA1LTQ1YzAtOGNiZC1kYTU2NTE4ZTc1MDQiLCJhdWQiOiJteV93ZWJfYXBwIiwic3ViIjoiMDdmMjkwZjZmNDQ3NmQ3MzBhNWMwMzFiZTk4ODY1YzZjOWJiMjQzNTVlNDcyYzk3ZGIzOTQwZjAzZDg0ZWY1MiIsImlzcyI6Imh0dHBzOi8vbGF1bmNoLnNtYXJ0aGVhbHRoaXQub3JnIiwiaWF0IjoxNTQzMDAwNzI4LCJleHAiOjE1NDMwMDQzMjh9.FOBYubrS81xw1QgQu2yqWqA7pyxzPI3JpniHdGQXZJedfI5LDqUnCuivMSmJNtqCIGp1pwqAa12e4dbL7N4DPrpEJv2jenj3TPHuk35GNrT6n4NFxS5ZFZgyOM425pnaC1t3Vkz_jzY_thHl-1ky_yHkPmfsZlXtyw5NwXqnkVNZ8W484fu_81kcqTcWPRhaYi7_93GfgCXLpZlyZQHy8YJqAVIxRRx9Ctw_3LP2H2WW7SF7HtSbP8IMM-BWOCx8NGSG3b4nou5Myls0i_gbL-vTC2Q_vDsPgjJPoFpDDRrKTj9VQMBUl0Wvcx5Mv1V4djG11rp_h0KSYuv5UGjG5g",
   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZWVkX3BhdGllbnRfYmFubmVyIjp0cnVlLCJzbWFydF9zdHlsZV91cmwiOiJodHRwczovL2xhdW5jaC5zbWFydGhlYWx0aGl0Lm9yZy9zbWFydC1zdHlsZS5qc29uIiwicGF0aWVudCI6ImIxZjAzNjVkLWY0MDUtNDVjMC04Y2JkLWRhNTY1MThlNzUwNCIsImVuY291bnRlciI6IjM1YmE4NzBhLWRmMTQtNDVhYy04YmJmLTE2ZTlkNmEwYWRmNCIsInJlZnJlc2hfdG9rZW4iOiJleUowZVhBaU9pSktWMVFpTENKaGJHY2lPaUpJVXpJMU5pSjkuZXlKamIyNTBaWGgwSWpwN0ltNWxaV1JmY0dGMGFXVnVkRjlpWVc1dVpYSWlPblJ5ZFdVc0luTnRZWEowWDNOMGVXeGxYM1Z5YkNJNkltaDBkSEJ6T2k4dmJHRjFibU5vTG5OdFlYSjBhR1ZoYkhSb2FYUXViM0puTDNOdFlYSjBMWE4wZVd4bExtcHpiMjRpTENKd1lYUnBaVzUwSWpvaVlqRm1NRE0yTldRdFpqUXdOUzAwTldNd0xUaGpZbVF0WkdFMU5qVXhPR1UzTlRBMElpd2laVzVqYjNWdWRHVnlJam9pTXpWaVlUZzNNR0V0WkdZeE5DMDBOV0ZqTFRoaVltWXRNVFpsT1dRMllUQmhaR1kwSW4wc0ltTnNhV1Z1ZEY5cFpDSTZJbTE1WDNkbFlsOWhjSEFpTENKelkyOXdaU0k2SW05d1pXNXBaQ0J3Y205bWFXeGxJRzltWm14cGJtVmZZV05qWlhOeklIVnpaWEl2S2k0cUlIQmhkR2xsYm5RdktpNHFJR3hoZFc1amFDOWxibU52ZFc1MFpYSWdiR0YxYm1Ob0wzQmhkR2xsYm5RaUxDSjFjMlZ5SWpvaVVHRjBhV1Z1ZEM5aU1XWXdNelkxWkMxbU5EQTFMVFExWXpBdE9HTmlaQzFrWVRVMk5URTRaVGMxTURRaUxDSnBZWFFpT2pFMU5ETXdNREEzTWpZc0ltVjRjQ0k2TVRVM05EVXpOamN5T0gwLjBtTlJnUG51RXMwT0dTS1htQlhlUUxENHU5UXZQa0NSQkR1VHc4S3o1ckEiLCJ0b2tlbl90eXBlIjoiYmVhcmVyIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBvZmZsaW5lX2FjY2VzcyB1c2VyLyouKiBwYXRpZW50LyouKiBsYXVuY2gvZW5jb3VudGVyIGxhdW5jaC9wYXRpZW50IiwiY2xpZW50X2lkIjoibXlfd2ViX2FwcCIsImV4cGlyZXNfaW4iOjM2MDAsImlkX3Rva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SndjbTltYVd4bElqb2lVR0YwYVdWdWRDOWlNV1l3TXpZMVpDMW1OREExTFRRMVl6QXRPR05pWkMxa1lUVTJOVEU0WlRjMU1EUWlMQ0poZFdRaU9pSnRlVjkzWldKZllYQndJaXdpYzNWaUlqb2lNRGRtTWprd1pqWm1ORFEzTm1RM016QmhOV013TXpGaVpUazRPRFkxWXpaak9XSmlNalF6TlRWbE5EY3lZemszWkdJek9UUXdaakF6WkRnMFpXWTFNaUlzSW1semN5STZJbWgwZEhCek9pOHZiR0YxYm1Ob0xuTnRZWEowYUdWaGJIUm9hWFF1YjNKbklpd2lhV0YwSWpveE5UUXpNREF3TnpJNExDSmxlSEFpT2pFMU5ETXdNRFF6TWpoOS5GT0JZdWJyUzgxeHcxUWdRdTJ5cVdxQTdweXh6UEkzSnBuaUhkR1FYWkplZGZJNUxEcVVuQ3Vpdk1TbUpOdHFDSUdwMXB3cUFhMTJlNGRiTDdONERQcnBFSnYyamVuajNUUEh1azM1R05yVDZuNE5GeFM1WkZaZ3lPTTQyNXBuYUMxdDNWa3pfanpZX3RoSGwtMWt5X3lIa1BtZnNabFh0eXc1TndYcW5rVk5aOFc0ODRmdV84MWtjcVRjV1BSaGFZaTdfOTNHZmdDWExwWmx5WlFIeThZSnFBVkl4UlJ4OUN0d18zTFAySDJXVzdTRjdIdFNiUDhJTU0tQldPQ3g4TkdTRzNiNG5vdTVNeWxzMGlfZ2JMLXZUQzJRX3ZEc1BnakpQb0ZwRERScktUajlWUU1CVWwwV3ZjeDVNdjFWNGRqRzExcnBfaDBLU1l1djVVR2pHNWciLCJpYXQiOjE1NDMwMDA3MjgsImV4cCI6MTU0MzAwNDMyOH0.Pn2yTlHaXmWj9a9UE4xgZpb_SXqBs7Ixto-SDT2q5KQ"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment