-
Notifications
You must be signed in to change notification settings - Fork 18
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
Allow user to store the current url in the session through options #25
Allow user to store the current url in the session through options #25
Conversation
I've modified the API to make more user friendly. I do not know what is the best way to expose a method to the agent. Ideally I would like to configure the callback as such in the login options:
Then use it on the call back from the agent as such:
And this would be the method to expose the stored current URL:
|
Hi @ctron, I finally managed to have the full flow working with Auth0 and the pull request submitted here. This is the implementation of the callback page on my app that I have implemented in order to leverage the url stored in the session when the IDP redirect me after successful login:
The part that I do not like is the reading of the session storage. This should be hidden in the agent somehow (using the Let me know what you think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry for intruding with review despite not being a member of project myself, but I also started working on this feature, so just adding some ideas I collected during that :)
Ultimately, it would be nice if handling of the redirect was also abstracted by yew-oauth2 - already working on it, so when your part gets through, I can finish and PR the rest of the code.
src/agent/state.rs
Outdated
@@ -1,6 +1,7 @@ | |||
pub const STORAGE_KEY_CSRF_TOKEN: &str = "ctron/oauth2/csrfToken"; | |||
pub const STORAGE_KEY_LOGIN_STATE: &str = "ctron/oauth2/loginState"; | |||
pub const STORAGE_KEY_REDIRECT_URL: &str = "ctron/oauth2/redirectUrl"; | |||
pub const STORAGE_KEY_CURRENT_URL: &str = "ctron/oauth2/currentUrl"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd consider this key name misleading, because at the moment when user actually reads it, it's already not the "Current url"
When I was playing with my own implementation, I considered something like STORAGE_KEY_POST_LOGIN_REDIRECT_URL
or STORAGE_KEY_ORIGINAL_URL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @kate-shine , I can rename it. It is not exposed (should not once we have a way to retrieve it via the client api or the handling of the local redirection by the component itself) to the outside world and I named it after the method I get it from self::get_current_url()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we should probably name the all local redirection as a process and have a way to 'activate' it as an extra local action when being redirected from the Idp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also prefer a name like "post login redirect", as that makes is pretty clear what the intention is. Also, feel free (if you like) to change the prefix from ctron
… seeing that now, I think I should have done that some time ago 🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends on how we want to see it? Do we want to name it as how we want to use it, or do we want to name it as what it is. It is the url of the ressource that initiated the flow but indeed we want to automatically redirect to it once the login is complete. Today the component does not do it automatically. So from a developer point of view it is the url the user tried to access before the authentication start and it is up to the dev to perform the Post login redirection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will rename it to post login url but for me this sound strange... Cause it gives the impression this post url is settable which is not. It is the original url. It is what we do with it that makes it a PostRedirectUrl. If you both agree on that. Let's do it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed if we manage to have everything handle internally, postLoginUrl makes full sens. My bad. :)
src/agent/mod.rs
Outdated
@@ -434,6 +444,16 @@ where | |||
let client = self.client.as_ref().ok_or(OAuth2Error::NotInitialized)?; | |||
let config = self.config.as_ref().ok_or(OAuth2Error::NotInitialized)?; | |||
|
|||
//If specified in the login options will store the current url in the session for retrieval | |||
// when coming back from IDP | |||
if let Some(options) = config.options.clone() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we actually need this to be configurable. It might be enough to just set this up in case the redirect_url
differs from current_url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's an interesting idea. There might be a drawback (which could be handled as well of course). What would happen if one time that URL differs and the next time it doesn't? In that case, the URL would still be set and evaluated when coming back.
The question is: does it hurt to always store the URL when starting, and then to handle this when it comes back? If (after the code exchange) it detects a different URL than the current, it could do the post-login redirect. Unless a flag is present which could be used to prevent that (if people don't like it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My approach and idea when I started working on it was to set it only if it differs from redirect URL and then redirect to it if it's present when evaluating callback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if I summarize:
- The user set a fixed redirectUrl (LoginOptions)
- If the user has set a fixed redirectUrl then we store the currentUrl as postLoginUrl in the session
- Once the process is finished, if there is a postProcessUrl in the session , we redirect to it instead of the returnURL
Sounds like a good scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd reframe the second point'ts condition as
- If the redirectUrl differs from the currentUrl
as that both means that redirect is needed and makes it obvious that fixed redirect url is set up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this handled by the check at the third point? "If there is a postProcessUrl, we redirect to it instead of the returnUrl"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kate-shine Nevermind :) Make full sens. I'm adapting my pull request.
Never be sorry because of that. Every constructive feedback is more than welcome! I really appreciate both of your input and help on this! |
src/agent/mod.rs
Outdated
/// Keep the current url in the session | ||
/// | ||
///Set this flag to true to store the current url for later retrieval in the session | ||
pub keep_current_url_in_session: Option<bool>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure this needs to be Option
, it looks like a default (false) would just work the same way.
I think it goes in the right direction. I also think that it might make sense to have yew-oauth2 to handle this automatically during the post-login processing. With the option to opt-out of it. Exposing the post login redirect URL on an API feels a weird. I think it's ok doing this, but there should be a reasonable default (with some way to customize this). I could imagine one or more of the following things:
Having those two options should allow one to have a reasonable default, but also enough freedom to customize the behavior. And feel free to choose different names (am bad with naming things). |
… for post login url
So to summerize:
The third part is missing. @kate-shine Can you do this part? |
Yep, I will happily try to tackle that one :) |
@@ -434,6 +434,8 @@ where | |||
let client = self.client.as_ref().ok_or(OAuth2Error::NotInitialized)?; | |||
let config = self.config.as_ref().ok_or(OAuth2Error::NotInitialized)?; | |||
|
|||
let post_login_url = Self::current_url().map_err(OAuth2Error::StartLogin)?; | |||
|
|||
// take the parameter value first, then the agent configured value, then fall back to the default | |||
let redirect_url = match options.redirect_url.or_else(|| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can now do a bit of a deduplication here, because match expression made sense mostly for lazy evaluation of current_url getter. (I'd personally also rename post_login_url
to current_url
to keep naming consistent with current context and for deduplication to make more sense if you go for it, but that's more a matter of taste :) )
let redirect_url = options.redirect_url.or_else(|| {
config
.options
.as_ref()
.and_then(|opts| opts.redirect_url.clone())
}).unwrap_or(post_login_url);
I'll really appreciate you both taking care of this. I won't have much time to review this until Friday. But I'll promise on Friday I will take a close look and hope to get it merged and released! |
Sent you few question on Matrix, I hope you don't mind :) |
@AlexandreRoba I think it's good to be merged, it just needs a rebase, sorry. |
BREAKING-CHANGE: In order to allow adding new options in the future, the structs LoginOptions and LogoutOptions have been made non-exhaustive. Adding some documentation on how to work with them.
@ctron Sorry I spend the last hour trying to "rebase" and can't seem to do it properly with a fork... Simply drop this merge request. Not sure it brings anything to the project. :( |
It was super helpful! Don't worry, I will finish the rebase and finish it in my branch, your commits are already there :) |
This PR was pulled in via #29 … many thanks to all of you! |
Some IDPs only support predefined sets of returned URL. We need a way to define a single returnUrl configured on the IDP and then from this page be able to find out what was the address of the local url that was used to initiate the login flow.
This PR allows the user to ask the agent through the options to store the current url in the session for later retrieval once the authentication flow has completed and the user returns to the site.