-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Controlling state in SMART launch #112
Comments
Sounds like an interesting use-case but I'm not sure I'm following. Can you provide a pseudo code example of what you would like to be able to do? |
Sure. This is a paradigm I've used in SMART apps a few times. The redirct_uri set in EHR environments has to match exactly with what's passed in so url query parameters cant be added dynamically. This means there's no way to pass data between routes without maintaining some sort of session on the client or server side. This can be done via cookies on the client side, which can be unreliable with EHR-based browsers. Cacheing the data on the server side and using the State value as the key to store and retrieve that data across routes allows you to maintain data across the launch process. route(/launch?healthcareOrgId=1&otherimportantvariable=2) route(/app) |
Well, this is how it is supposed to work, except that it uses sessionStorage in the browser instead of cookies. That "state" is created at launch time (when const key = sessionStorage.SMART_KEY; // random string
const state = sessionStorage[key]; I don't think you wan't to be able to customize that key name just to get access to the key. What you really need is a way to augment that state. Even though it is theoretically possible to access and modify the state, that might not work in practice because the state is created by a function which will redirect immediately after that... With that said, what sounds like a better idea to me is to add a placeholder for custom data in the state. That might look like so: FHIR.oauth2.authorize({
clientId: "my_web_app",
scope: "patient/*.read",
data: { /* my custom data */ }
});
// later...
FHIR.oauth2.ready()
.then(client => client.getState(”data”))
.then(console.log)
.catch(console.error); What do you think about that? |
To be clear, I'm referring to the state string value that is a uuid, not the full object the library refers to as State in getState(). My preference would be that this library just manages the SMART auth concepts. If you allow us to optionally pass in the state uuid then it creates a less "opinionated" experience and shouldn't introduce any breaking change on your side, because we're just replacing an auto-generated value with an optional parameter. I think the library would be more flexible if it allowed the user to dictate the state value. My use-case is probably the primary driver of this, but I think session management outside of the client object can be useful for other purposes. Allowing the user to pass in a state in lieu of it being auto-generated achieves that. Your proposed architecture only works if I have access to the fhir.oauth2 client object. I'm currently working on an Auth0 authentication mechanism that uses additional redirects after obtaining the fhir.oauth2 client object. I need some information available from this fhir.oauth2 client object in those routes though. So ultimately I need to use a second session storage mechanism, and I'd prefer to establish that at the initiation of the launch via the State key so I can use the same identifiers throughout the process. |
OK, that makes sense. It may be more complicated than it looks though.
|
Wondering if this idea can be revived. Using the state parameter in OAuth2 flows is a common way to maintain state throughout the handshake process. A standard OAuth2 server will pass back whatever you pass to it in the Object state: If The current implementation of the authorize function in this library always generates We currently attempt to maintain additional state by setting a cookie before the authorize request and then reading it back in during the completion step of the authorization. This is unreliable in many instances, especially with embedded browsers in some EHRs, which will not preserve cookies used in this way. |
Guys, have you found any solution how to overcome the single SMART_KEY limitation without forking? |
The State parameter is a useful tool to control session data across the SMART launch. For example url paths can be layered onto the base url to indicate that a particular organization or user type is performing the launch, and that data can be stored in the session so it's available after the redirect. This isn't possible if the State value cannot be controlled.
Could we add code to support inclusion of state as a parameter to the authorize() function then set stateKey to the state parameter if it exists? This shouldn't impact current code, but will allow additional development flexibility.
The text was updated successfully, but these errors were encountered: