Skip to content
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

Fix post logout redirect, add config for default #40

Merged
merged 23 commits into from
Jan 23, 2020

Conversation

balazsorban44
Copy link
Contributor

@balazsorban44 balazsorban44 commented Nov 26, 2019

By submitting a PR to this repository, you agree to the terms within the Auth0 Code of Conduct. Please see the contributing guidelines for how to create and submit a high-quality PR for this repo.

Description

When invoking the default /logoutendpoint, we will try to attempt to get the returnURL from req.query.returnTo. In addition, I added the possibility to provide post_logout_redirect_uri in the config of auth(), like so:

express()
//...
.use(auth({
    baseURL: "http://localhost:8000",
    post_logout_redirect_uri: "http://localhost:8000",
    required: false,
    idpLogout: true
  }))
// ...

@joshcanhelp I also did a change which I ask you to give a comment on. I moved the session destroy part under the client.endSessionUrl() call, because req.openid.tokens becomes undefined after destroy. After this, my IdP redirects correctly as referred to in the issue referenced under.

References

This issue is an improvement after the discussion in #35.

Testing

As of now I only tested it locally, but everything seems to work fine. If requested and/or the way I implemented it is accepted, I can try to create some tests in logout.tests.js

  • This change adds test coverage for new/changed/fixed functionality

Checklist

Again, if my changes are accepted, I can document the changes.

  • I have added documentation for new/changed functionality in this PR or in auth0.com/docs
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not master

@balazsorban44
Copy link
Contributor Author

ping @joshcanhelp 🙂

Copy link
Contributor

@joshcanhelp joshcanhelp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@balazsorban44 - Appreciate your patience here. This is really close, just a few small changes and we'll get this merged in. Also, would be great to get a few tests written to make sure that the URL is coming through in all the cases.

lib/config.js Outdated Show resolved Hide resolved
lib/context.js Outdated Show resolved Hide resolved
lib/context.js Outdated Show resolved Hide resolved
@balazsorban44
Copy link
Contributor Author

Moved some parts around a bit in the tests, hopefully it is OK with you. Moved the before call into a setup function, that takes some params to slightly change the result (able to modify auth params per test now, with a single setup).

Used this great article by Kent.C.Dodds: Avoid Nesting when you're Testing

Also moved repetitive strings to a single place (mockData, authOParsedUrl), so typos and forgetting to replace strings (eg.: version number in pathname) at all the places are out. (That part is only my own preference for the above mentioned reasons, might have been a bit fast with that, can change back if you wish)

@joshcanhelp
Copy link
Contributor

RE: the test changes ... while I'm not under any delusions that the current way is the right way 😄, I'm a little worried about changing the whole testing paradigm in a single file. It's also not clear what tests were added for this functionality. Maybe we can address that approach in a different PR?

@joshcanhelp
Copy link
Contributor

@balazsorban44 - Are you able to wrap this one up in the near future? We're going to put out a release next week and it would be great if this was part of that. My main issue in merging this is the big changes in the logout tests. Would like to see primarily adding there, not a refactor.

If you've moved on from the library, let me know and we'll handle it on our end.

Thank you!

@balazsorban44
Copy link
Contributor Author

Hi, I am back after a long holiday. So to sum up, what is missing so this can be merged? (apart from fixing the conflicts).

@joshcanhelp
Copy link
Contributor

@balazsorban44 - Thanks for checking in. Main thing for me is to just see added tests for this functionality rather than a refactor of how the existing tests work. Also the comment about redirectUriPath, that makes more sense as a path since it will not be external.

@balazsorban44
Copy link
Contributor Author

OK, will fix next week 😉

@balazsorban44
Copy link
Contributor Author

balazsorban44 commented Jan 13, 2020

Fixed it, but because of the merged in master, some tests are failing.

Both postRedirectUri and logout query string returnTo are relative paths now, which are concatenated with the baseURL.

Copy link
Contributor

@joshcanhelp joshcanhelp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sticking with this @balazsorban44! I fixed those tests in master so you should be able to rebase and pass here.

Just to be clear, this assumes that any customization it receives is (parameter, config key) is a relative path? Makes sense that it would be consistent across the board.

The one thing we probably want to change here is postLogoutRedirectUri -> postLogoutRedirectPath so it's consistent with the other internal path configurations.

Otherwise, looks great!

@balazsorban44
Copy link
Contributor Author

balazsorban44 commented Jan 14, 2020

We are close! (Sorry if it is a bigger task for such a small PR than you expected 😅. If you only wish to be done with this for now, and rather do this discussion later in an issue for example, just give me a word, and I'll just do the required changes so you will be able to include it in the release.)

I know it is a bit back-and-forth, but I just looked up some docs before I made the name change:

1. OpenID Connect Session Management says:

OPTIONAL. URL to which the RP is requesting that the End-User's User Agent be redirected after a logout has been performed. The value MUST have been previously registered with the OP, either using the post_logout_redirect_uris Registration parameter or via another mechanism. If supplied, the OP SHOULD honor this request following the logout.

2. IdentityServer End Session Endpoint says:

If a valid id_token_hint is passed, then the client may also send a post_logout_redirect_uri parameter. This can be used to allow the user to redirect back to the client after sign-out. The value must match one of the client’s pre-configured PostLogoutRedirectUris.

3. ASP.NET Core says:

The uri where the user agent will be returned to after application is signed out from the identity provider. The redirect will happen after the SignedOutCallbackPath is invoked.
This URI can be out of the application's domain. By default it points to the root.

Auth0 mentions postLogoutRedirectUri in some form here as well.

Maybe none of these are relevant in our case, but I just wanted to clarify if you want to go that way, and really call it postLogoutRedirectPath, because although there is nothing wrong with it in my opinion, but it does not seem to appear in the OIDC spec in that form. If you look at 1. and 2., they do say that you MUST register this URI beforehand. Using a relative path kind of does that, I guess...?

So I don't say I wouldn't change it to postLogoutRedirectPath, but I first would like to hear your opinion about this.

@joshcanhelp
Copy link
Contributor

Appreciate the research and thought on this @balazsorban44. And no worries about this becoming a long discussion. I would much rather talk this through completely and make a good choice than have to deal with pain points later.

I typed out a bunch of stuff and ended up deleting it because the spec does not mention anything about the base domain of those post logout URIs. I was assuming that those needed to be on-site but that's not true according to the spec. As long as it's registered on the OP, then it's fine.

I'm going to run this by my team quickly but I'm now in agreement here about the uri part. Thank you again for starting the discussion!

One thing that would be nice here is to accept a path or a URI and append the base URL if it's a path. Does that sound reasonable?

@balazsorban44
Copy link
Contributor Author

Yes, supporting both may be the most reasonable decision. :) I will have a look at it.

@joshcanhelp joshcanhelp added this to the v0.7.0 milestone Jan 15, 2020
@balazsorban44
Copy link
Contributor Author

balazsorban44 commented Jan 16, 2020

Hmm. 🤔 Should full URIs be supported for returnTo as well? 🔒

In that case I could also create an optional postLogoutRedirectUris array in the config, that accepts a list of relative paths or URIs, and force params.returnTo and req.query.returnTo to be in that list, making it mandatory to pre-register. I am not 100% sure though how I should handle an error then if it occurs in the logout() function.

UPDATE:
I went ahead, and made those changes, I can revert it if you disagree, but I now do the following:

  1. If postLogoutUri is a relative path, it is prepended with baseURL.
  2. If postLogoutUri is a full URI, we can safely redirect to it, because it was defined in the backend.
  3. If returnTo parameter is a relative path, we proceed as in 1.
  4. If returnTo parameter is a URI starting with baseURL, proceed, cause it is safe.
  5. If returnTo parameter is a URI with an external domain, only proceed if the URI is explicitly registered in postLogoutRedirectUris. Otherwise throw an error:
new Error(`returnTo (${returnTo}) URI was not registered in config's postLogoutRedirectUris.`);

Copy link
Contributor

@joshcanhelp joshcanhelp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delayed response here. Let me know if you have any questions about my feedback here.

index.d.ts Outdated Show resolved Hide resolved
lib/config.js Outdated Show resolved Hide resolved
lib/context.js Outdated Show resolved Hide resolved
lib/context.js Outdated Show resolved Hide resolved
test/logout.tests.js Show resolved Hide resolved
Copy link
Contributor

@joshcanhelp joshcanhelp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong review type ... comments above.

@balazsorban44
Copy link
Contributor Author

balazsorban44 commented Jan 23, 2020

I reverted my postLogoutRedirectUris changes then. See above why the tests must include '/'.

Copy link
Contributor

@joshcanhelp joshcanhelp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks and works like a charm. Thanks @balazsorban44!

@joshcanhelp
Copy link
Contributor

@balazsorban44 - I tried to rebase master for you but your branch won't allow pushes. Can you resolve the conflicts here and push? If you're able to rebase the commits to cut down on the number there, that would be helpful as well.

@balazsorban44 balazsorban44 mentioned this pull request Jan 23, 2020
1 task
@balazsorban44
Copy link
Contributor Author

@joshcanhelp Should be OK now, I did not have any merge conflicts though.

@joshcanhelp joshcanhelp changed the title post logout redirect Fix post logout redirect, add config for default Jan 23, 2020
@joshcanhelp joshcanhelp merged commit 68d6190 into auth0:master Jan 23, 2020
@balazsorban44 balazsorban44 mentioned this pull request Mar 28, 2020
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants