Discourse redirects to the OAuth server after loading `/?authComplete=true`

The flow is a bit complex. OAuth is the only allowed login on the Discourse instance. The whole idea is for the user to land back on the site they were before they were asked to create an account on the OAuth server.

It goes like this:

  • User clicks Login
  • Thanks to a custom code snippet, it goes directly to the (custom) OAuth server login page
  • User clicks Create an account and creates an account on the OAuth server
  • A confirmation e-mail is sent

Meanwhile, the OAuth server stores that when this particular e-mail is confirmed, and as soon as the user logs in again, it must redirect them to https://[discourse-server]/auth/oauth2_basic to automatically initiate a login process.

The issue is here.

  • When the user clicks the OAuth server confirmation link in the same browser session (used from the first step)

    • The user is redirected to https://[discourse-server]/auth/oauth2_basic
    • This starts the OAuth2 login process
    • The user ends up on https://[discourse-server]/?authComplete=true, connected.
    • ^ this is the wanted behavior
  • When the user clicks the OAuth server confirmation link in a new browser session

    • The user is redirected to https://[discourse-server]/auth/oauth2_basic
    • This starts the OAuth2 login process
    • The user ends up on https://[discourse-server]/?authComplete=true, connected
    • The user is somehow redirected to https://[oauth2-server]/
    • ^ this is the issue

A screenshot to go with the text…

Text to go with the screenshot…

  • #1 | The user has just confirmed its e-mail and successfully signs in, redirected to its profile page
  • #2 | The profile page is where the custom redirection I was talking about is taking place, so the user is redirected to https://[discourse-server]/auth/oauth2_basic
  • #3 | Discourse then redirects the user back to the OAuth server to initiate the login process
  • #4 | OAuth authorization
  • #5 | Discourse callback, redirecting the user to /?authComplete=true
  • #6 | Bunch of assets loading (filtered in the devtools)
  • #7 | Boom, out of nowhere, the user is redirected to the OAuth server root path
  • #8 | … then redirected to its profile since they’re already logged in

So I’m guessing the extra redirect has something to do with a session-based storage.

Can someone point me to an area of the Discourse codebase where something like this would occur?

I’m already digging but some help would be appreciated. Thanks a lot.

2 Likes

Do you have any ideas @david?

1 Like

I’m not sure exactly what’s going on. @ryancey if you are able to share a link to the site I’d be happy to take a quick look.

Some of the logic around redirection is in

https://github.com/discourse/discourse/blob/master/app/controllers/users/omniauth_callbacks_controller.rb#L54-L90

We use the omniauth origin system, which uses the referrer to determine the user’s starting location: https://github.com/omniauth/omniauth/wiki/Saving-User-Location.

That can be overridden by the destination_url cookie, or the origin= URL parameter. You could try using https://[discourse-server]/auth/oauth2_basic?origin=/, to ensure that your users always end up on the forum homepage.

I know @LeoMcA recently made some improvements here, so make sure you’re running a recent version of Discourse.

3 Likes

I explain the problem I was seeing (and link to the changes I make) in this topic: Redirect after logout with full screen login

The difference here is that the issue I faced only happened after logout, not during the login process (but I imagine the problem lies in a similar section of code).

This kind of change in behaviour across sessions strikes me as cookie oddness, so maybe have a look there.

I’ve sorta-kinda managed to decrypt session store cookies on live Discourse sites by copying this function into the rails console before, but it’s messy. For proper debugging I’d suggest running a dev image in docker and adding this to ApplicationController to get it to print the current session cookie on every request.

before_action :print_session_cookie

def print_session_cookie
  pp session
end

I imagine you’re already doing this, but just in case you’re not, I wouldn’t rely on github search to do digging like this. I find Atom’s search (other text editors are available) far more fast and reliable.

3 Likes

Hi @ryancey - thanks for the extra info via PM. I’ve now improved the behaviour so it should work better for this situation:

https://github.com/discourse/discourse/commit/1299c94a5282693e57661f156b4072e3c890d7cc

Please give it a try and let us know if it works.

5 Likes

Just tested and it seems fixed :+1:

Thanks a lot @david.

5 Likes

This topic was automatically closed after 5 days. New replies are no longer allowed.