The redirect response does not send the hash fragment (tokens) to the server-side

I am having issues with the Auth0 callback. The problem is that after authentication, the redirect coming back to the browser (Chrome in this case) contains a # fragment and the browser is not sending this hash fragment to the redirected URL. See below.

Here is the callback.

Request URL:https://tapaas.auth0.com/login/callback?state=B0DYX2akGxLvkddRxPQ3JbYo0cIeRRRR&code=4/3rfgi3VLyS1bcO1Ni8GNNNdPeCrihaITVFeeSV_yYc
Request Method:GET
Status Code:302 Found
Remote Address:52.53.55.133:443

Response Headers:

Location: https://localhost:5001/callback#access_token=kUsPx6ohjUD7UCtm&expires_in=86400&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3RhcGFhcy5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMTYxNjY0NjA5OTc0MDQzNTkwODAiLCJhdWQiOiJ3UFc4b1FzWkJad1FLQ09LY3NlcmpORmlPR3dHeDZ4USIsImV4cCI6MTQ5MTY0Mjc3NSwiaWF0IjoxNDkxNjA2Nzc1fQ.kPLlC1m6xuV2-kizSEzPtTMtMMERl4VKSMVJL22sUjU&token_type=Bearer

The browser then issues a request for https://localhost:5001/callback without the #fragment containing all the useful information.

Request URL:https://localhost:5001/callback
Request Method:GET
Status Code:302 Moved Temporarily
Remote Address:::1]:5001

Any ideas how to get the JWT token to come back on the callback?


Update:

The reason for this is that my use case is a little different to any of the boilerplate cases that are documented by Auth0. We have a web app but we don’t want the web app (client or server code) to have any knowledge of Auth0. We have an openresty nginx reverse proxy sitting in the way. It checks requests and redirects to the standard Auth0 authentication.

The Auth0 authetication callback passes the JWT token which is picked up by nginx and set as a cookie for the user session. Further requests will validate the JWT token from the cookie, unpack the user identity and authorisation roles and place those as headers to the server application to which the request is then proxied.

The behavior you’re experiencing is the expected one, more specifically, the fragment component of an URL is never sent by the browsers to the underlying web server.

The underlying authentication protocol (OAuth2/OIDC) specifies a response_type parameter that allows the client application to state what type of response it wants to process. This response type maps to the concept of an authorization grant as specified in OAuth2. There are a few other authorization grants, but the ones most relevant for web application use are:

  • the implicit grant - by default, the success response will contain the requested tokens and is returned as part of the URL fragment component. It’s meant to be used by browser-based applications (think SPA’s) that have their logic running on the client-side and as such can access the fragment component of the redirect URL response.

    https://example.com/callback#id_token=wsx

  • the authorization code grant - by default, the success response will contain an authorization code and is returned as part of the URL query component. It’s meant to be used by regular server-side web application that have their logic run on the web server and as such can maintain a client secret used during the exchange of the received code by the actual tokens.

    https://example.com/callback?code=xyz

If your application is a regular web application you may consider switching to the authorization code grant which would return the code in the query component that would indeed be sent to the server-side logic associated with the specified redirect URL.

Additionally, you can also influence the default behavior and for example indicate that you want to perform an implicit grant, but prefer to receive the response using an HTTP POST to the redirect URL instead of the response being included in the fragment component of an HTTP redirect. This is accomplished using the response_mode OAuth2 parameter; for reference information on this check: OAuth 2.0 Authorization Framework

Thanks for the detailed answer. I have a much better understanding now and have managed to get things going now based upon your advice.

(the question was also updated with the exact scenario that triggered the problem)

Thanks for the detailed answer. I have a much better understanding now and have managed to get things going now based upon your advice.

(the question was also updated with the exact scenario that triggered the problem)