Open rpwagner opened 1 month ago
@rpwagner – AuthorizationManager.login()
and AuthorizationManager.handleCodeRedirect()
will accept an optional options parameter. To pass query parameters through the OAuth handshake you can specify additionalParams
.
manager.login({ additionalParams: { state: '...' }});
But, taking a look a the internals here, I think you will encounter an Invalid State
error when you call handleCodeRedirect
– I can get that fixed.[^1]
However, the state
should be used to prevent cross-site request forgery (see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1). If you don't provide a value, the SDK is creating a cryptographically strong random value that meets the OAuth spec requirements, if you provide your own you'll want to make sure you're doing some additional encoding rather than just supplying something like a.csv
.
I can tell you in the applications we've been using the AuthorizationManager
in, we've been managing application state outside of the OAuth handshake parameters (e.g. localStorage
/sessionStorage
values we reinstantiate post-handshake).
To do this, where you call manager.handleCodeRedirect
you'll likely want to pass { shouldReplace: false }
, process your storage then redirect on your own (e.g. window.location.replace
).
[^1]: EDIT: This is addressed in #319 and will be available in the next patch release.
Thanks @jbottigliero. Session storage was what I also considered.
Is this roughly what you're describing?
UI.SIGN_IN.addEventListener('click', () => {
/**
* This will redirect the user to the Globus Auth login page.
*/
let queryString = window.location.search;
sessionStorage.setItem("queryString", queryString);
manager.login();
queryString = sessionStorage.getItem("queryString");
window.location.search = queryString;
});
Is this roughly what you're describing?
Rather than reading the value after .login()
you would read that when the user is authorized (after the OAuth handshake).
Extending that basic example, I think you could do something like...
UI.SIGN_IN.addEventListener("click", () => {
/**
* This will redirect the user to the Globus Auth login page.
*/
let queryString = window.location.search;
// You'll set the value before you prompt for login.
sessionStorage.setItem("queryString", queryString);
// Since this will initiate the OAuth redirect, you can't really do any processing afterward.
manager.login();
});
// ...
if (manager.authenticated) {
const queryString = sessionStorage.getItem("queryString");
if (queryString) {
sessionStorage.removeItem("queryString");
// do something;
}
What problem are you trying to solve?
When a page receives a set of query parameters like
https://example.org/plot.html?file=a.csv
I would like to know the appropriate way to persevere the query stringfile=a.csv
after a login redirect. I believe this is typically handled via thestate
parameter in the OAuth flow, though I could be mistaken.We are using this model to have a single page that view and interact with data from Globus Collections that require access tokens. This way, way can have a single viewer page and load different files based on the query parameters. Examples of doing this for public data are in our Cheap and FAIR template repo (see the view.md and chart.md pages).
Describe the solution you'd like
It would great to have an example like the basic login page that shows how to use the state parameter or other means to do this.
Describe alternatives you've considered
As a workaround, I will try collecting the parameters prior to creating the login manager and calling
manager.handleCodeRedirect()
orlogin()
.