Stream: smart
Topic: Unable to get state from launch
Christa Wan (May 31 2021 at 17:36):
Hi,
During the initial launch of a SMART client app from the logica sandbox or SMART app launcher, we receive the following error:
Error: No state found! Please (re)launch the app.
Does anyone know how to solve this ?
Thanks,
Christa, @Joel Francis , @Alex Goel , @Paul Puscas
Alex Goel (May 31 2021 at 17:48):
@Vladimir Ignatov we saw you posted an answer to similar question on github https://github.com/smart-on-fhir/growth-chart-app/issues/18
but we're trying to launch the app through Firebase (firebase.google.com/).
We noticed that the state is getting passed through the URL, but our app (using the SMART JS framework) isn't doing anything with it it seems
Joel Francis (Jun 01 2021 at 02:02):
Alex Goel said:
Vladimir Ignatov we saw you posted an answer to similar question on github https://github.com/smart-on-fhir/growth-chart-app/issues/18
but we're trying to launch the app through Firebase (firebase.google.com/).
We noticed that the state is getting passed through the URL, but our app (using the SMART JS framework) isn't doing anything with it it seems
@Nikolai Schwertner
Vladimir Ignatov (Jun 01 2021 at 13:37):
Can you explain what you mean by "launch the app through Firebase"? Who is launching it and how? Is it a browser app or NodeJS? Is it EHR launch or standalone? Can you provide a link to the app itself?
David Winters (Jun 01 2021 at 17:35):
@Christa Wan I ran into a similar issue trying to get the client-js
library working with a vendor sandbox. Have you tried putting some debugging statements around where this error is getting thrown?
David Winters (Jun 01 2021 at 17:42):
You need to first launch by calling FHIR.oauth2.authorize()
which takes your configuration and creates a redirect url and then performs the redirect. client-js
stores information in the local store, which is referenced after authorization redirects back to your app. You should have a call to FHIR.oauth2.ready()
on the page of this final redirection. The issue I was running into was that I didn't have my redirect url specified correctly.
Christa Wan (Jun 01 2021 at 17:42):
Hi @Vladimir Ignatov ,
We are trying to use the Logica sandbox to provide patient data to our Node.JS application that is currently running on Firebase. The app works on the SMART app launcher without a proxy, but we require a proxy to forward the information to our app due to an issue we had with the CORS header. Once we add the CORS header via proxy, we get the error as specified above
Error: No state found! Please (re)launch the app.
The app can be found at this link: https://smart-on-fhir-17eef.web.app/, and it is an EHR Launch. We are receiving the state from the URL from Logica (seen through fiddler), but for some reason we are still getting this error.
Thanks.
Joel Francis (Jun 01 2021 at 17:46):
@Vladimir Ignatov @David Winters thank you for your responses.
The application is hosted on Firebase - what I mean by this is the project directory and resources are served using Firebase. The app is launched using the Logica STU3 sandbox. @David Winters in reply to your suggestions about CORS, to get around it, we use a proxy to inject the Allow-Cors header into the request and pass it through to the app hosted on Firebase.
What we are finding is that the fhire-client.js is complaining on line 583 of smart.ts where it checks the url parameters for the state and complains of no state and asks re-launch of the app. Using fiddler we are able to see the re-direct to our index page with a "code" and a "state" parameter both obviously not empty.
@Vladimir Ignatov we will host our proxy on a server and give you access to the app as soon as we can. We currently have the proxy on localhost. Thank you @Vladimir Ignatov and @David Winters for the response and help.
@Alex Goel
Christa Wan (Jun 01 2021 at 17:46):
Hi @David Winters ,
We have both of these calls - The first one FHIR.oauth2.authorize()
in our launch.html, which specifies the Redirect URI as index.html, which contains our call to the FHIR.oauth2.authorize()
function.
David Winters (Jun 01 2021 at 17:56):
@Joel Francis have you looked into line 511? state
is getting pulled from storage, which I think comes from the session if you're in the browser.
David Winters (Jun 01 2021 at 18:00):
Sounds like somehow your authorize()
and ready()
calls aren't working off of the same session.
Vladimir Ignatov (Jun 01 2021 at 18:24):
Sounds like somehow your authorize() and ready() calls aren't working off of the same session.
Exactly. Your SessionStorage
is empty but it shouldn't be. How is your launch_url
configured in Logica? Is it on the same origin
as your app ( https://smart-on-fhir-17eef.web.app)? Perhaps the proxy is messing with that (although it does work with the SMART Launcher)?
Joel Francis (Jun 01 2021 at 19:45):
@Vladimir Ignatov @David Winters
The registered launch url in the logica sanbox and the redirect_uri are different and we get the same error consistently on Logica and the SMART app Launcher.
The Launch_URL is to our proxy server which is just literally adds the CORS header to the request and then forwards it to the Launch.html of our app where we call the ``` FHIR.oauth2.authorize()```` . Then the redirect is back to the app but to the index.html page where we call the ready() function.
So what the both of you are saying is that there is somehow two different sessions and no preservation of the "state" of the fhir-client.js state and not the "state" that comes from the FHIR server????
Without the proxy we were encountering a CORS issue. So @David Winters , using your amended fhir client, we can add the cors header?
Vladimir Ignatov (Jun 01 2021 at 19:57):
In this case "state" is just an entry in SessionStorage
. SessionStorage is namespaced per origin. If launch.html is hosted at http://a/launch.html, it will write a few things to SessionStorage
, assuming that app.html
will find those after the redirect. However, if the app is on http://b/index.html, it will not be able to see anything that launch.html
wrote... Can't you run them both through the same proxy then?
Joel Francis (Jun 01 2021 at 20:02):
Vladimir Ignatov said:
.. Can't you run them both through the same proxy then?
@Vladimir Ignatov trying to understand by reiterating what you are saying - have the application redirect back to the proxy and then call index.hmtl in which case index.html has to be part of the same cluster or on the same host?
Vladimir Ignatov (Jun 01 2021 at 20:13):
What I'm saying is that in Logica, if your "Launch URL" is https://my.proxy/launch.html
, then your "Redirect URL" should be https://my.proxy/app.html
Joel Francis (Jun 01 2021 at 20:20):
Vladimir Ignatov said:
What I'm saying is that in Logica, if your "Launch URL" is
https://my.proxy/launch.html
, then your "Redirect URL" should behttps://my.proxy/app.html
exactly! @Vladimir Ignatov we will give that a try. Thanks @Vladimir Ignatov and @David Winters
Nikolai Schwertner (Jun 02 2021 at 14:43):
In general, there is no requirement that the launch and redirect URIs of an application are on the same domain either by SMART or Logica. It just happens that the SMART JS client (that you are using) has this limitation.
Christa Wan (Jun 02 2021 at 14:45):
Hi @Vladimir Ignatov ,
We have tried to replace the Redirect URI with our proxy server. However, we are now getting the CORS header error again, as shown below: Screen-Shot-2021-06-02-at-10.43.04-AM.png
Thanks,
Christa
Joel Francis (Jun 02 2021 at 14:46):
Nikolai Schwertner said:
In general, there is no requirement that the launch and redirect URIs of an application are on the same domain either by SMART or Logica. It just happens that the SMART JS client (that you are using) has this limitation.
@Nikolai Schwertner thank you for pointing this out as were were wondering why have the redirect_uri in the first place.
Vladimir Ignatov (Jun 02 2021 at 15:50):
Nikolai Schwertner said:
In general, there is no requirement that the launch and redirect URIs of an application are on the same domain either by SMART or Logica. It just happens that the SMART JS client (that you are using) has this limitation.
That might be true, but it is the only way to to provide out of the box SMART auth in the browser. The alternative would be to ask users to set up and rely on some kind of external storage service (rather than SessionStorage), just to manage the "local" state - not impossible but too complicated for client-side apps...
Anyhow, if the launch and redirect urls are on the same domain, then it should be working, so the real question is why doesn't it? Is the token endpoint (and /metadata) sending CORS headers? What exactly is the response status code/message (it says "does not have HTTP ok status" in the screenshot)?
Alex Goel (Jun 02 2021 at 19:41):
We get the OK Status if we use the proxy and the redirect_uri pointing at our SMART app and not the proxy
Alex Goel (Jun 02 2021 at 19:41):
but the SMART app doesn't do anything with the state
Vladimir Ignatov (Jun 02 2021 at 19:56):
Sorry, but I cant't try it (has to be done from within your Logica account)
Try executing this in console localStorage.debug = "FHIR.*"
, then make sure your console is configured to persist logs. Then re-launch and see if you are getting anything useful in the console.
David Winters (Jun 02 2021 at 20:39):
The registered launch url in the logica sanbox and the redirect_uri are different and we get the same error consistently on Logica and the SMART app Launcher.
When you say the SMART app Launcher, do you mean the public SMART sandbox? If that's the case I would focus on getting the app working with that first.
Alex Goel (Jun 02 2021 at 23:17):
Thanks Vlad we'll try the debug.
We're getting the same Error: No state found! Please (re)launch the app.
failure to pass the state on both the SMART App Launcher: https://launch.smarthealthit.org/
Vladimir Ignatov (Jun 02 2021 at 23:23):
You are probably using wrong settings. Just click the "Launch App" button here: https://launch.smarthealthit.org/?auth_error=&fhir_version_1=r4&fhir_version_2=r4&iss=&launch_ehr=1&launch_url=https%3A%2F%2Fsmart-on-fhir-17eef.web.app%2Flaunch.html&patient=&prov_skip_auth=1&provider=&pt_skip_auth=1&public_key=&sb=&sde=&sim_ehr=0&token_lifetime=15&user_pt=
Alex Goel (Jun 02 2021 at 23:35):
Screen-Shot-2021-06-02-at-19.33.44.png
It works fine when we launch just the app without the proxy on the sandbox. It's able to receive the patient. It does not pass the state when we use the proxy to get around the CORS issue with Logica or with the SMART sandbox.
Alex Goel (Jun 02 2021 at 23:37):
Our proxy is here: https://stormy-plateau-96241.herokuapp.com/ our app launch is here: smart-on-fhir-17eef.web.app/launch.html you can replicate our error on the sandbox. It's the same on Logica
Joel Francis (Jun 03 2021 at 13:40):
Alex Goel said:
Our proxy is here: https://stormy-plateau-96241.herokuapp.com/ our app launch is here: smart-on-fhir-17eef.web.app/launch.html you can replicate our error on the sandbox. It's the same on Logica
Hello @Vladimir Ignatov @David Winters
We finally have it working using the SMART sand box and our proxy adds the following headers. It still fails on Logica with a CORS issue.
res.header("Access-Control-Allow-Origin", process.env.ORIGIN || "*");
res.header("Access-Control-Allow-Methods", process.env.ORIGIN || "POST, GET, OPTIONS, DELETE, PUT");
res.header("Access-Control-Allow-Headers", process.env.ORIGIN || "append,delete,entries,foreach,get,has,keys,set,values,Authorization");
Thanks @Vladimir Ignatov and @David Winters for the help and guidance. Our next step is to try it on another sandbox like Cerner.
Vladimir Ignatov (Jun 03 2021 at 13:55):
To be clear, the SMART sandbox does not have a CORS issue and you don't need that proxy. My advice is:
- If Logica really does have a CORS issue, report that, give them time to fix it and use other sandboxes until they do.
- Don't use that proxy on the SMART sandbox, Cerner or anywhere else
Last updated: Apr 12 2022 at 19:14 UTC