auth0/auth0-react

loginWithRedirect behaving different between dev and prod with nextjs

ian-weir opened this issue · 8 comments

Checklist

Description

I'm working on a NextJS app that is completely being rendered statically by way of NextJS's Automatic Static Optimization feature. Using the next dev and next build + static export or next start has different behaviour when using LoginWithRedirect.

In dev mode it behaves as expected passing redirect_uri, organization and invitation in the authorization parameters.

When running in production mode the organization and invitation parameters are not respected in the resulting url used for redirection.

Reproduction

  1. Use a nextjs project but only with front end functionality, nothing server side
  2. Conditionally pass organization & invitation parameters when present.
  3. Redirect url doesn't contain either of those parameters

Additional context

Using Next 13.3.2

Query params in production mode also have a series of strange parameters at the beginning:

https://{DOMAIN}.us.auth0.com/authorize?0=d&1=2&2=5&3=m&4=V&5=V&6=R&7=Z&8=d&9=H&10=B&11=C&12=Q&13=T&14=h&15=k&16=c&17=X&18=R&19=P&20=Y&21=k&22=x&23=Y&24=d&25=m&26=s&27=w&28=S&29=m&30=J&31=J&32=T&33=E&34=t&35=R&36=b&37=2&38=1&39=V&40=b&41=E&42=V&43=W&44=a&45=k&46=h&47=C&48=Z&49=W&50=J&51=x&52=S&53=T&54=J&55=p&56=a&57=w&58=%3D&59=%3D&client_id={CLIENT_ID}&scope=openid+profile+email+offline_access&audience={AUDIENCE}&response_type=code&response_mode=query&state={STATE}&nonce=cGQ3X35mTjNTZWpRNWNxYVZMQ0YwWFI5LnhrMUMtX0hSV3BXbER5SGZjLg%3D%3D&redirect_uri={REDIRECT_URI}&code_challenge=CfuO2VKa_FGNvb9Ol_1CK04zu2QugavZyOg3_InNUmI&code_challenge_method=S256&auth0Client={AUTH0_CLIENT}

Redirect url in dev mode looks like:
https://dev-ws8z8uiswqyyrcam.us.auth0.com/authorize?client_id={CLIENT_ID}&scope=openid+profile+email+offline_access&audience={AUDIENCE}&organization={ORGANIZATION}&redirect_uri={REDIRECT_URI}&response_type=code&response_mode=query&state=RkdiTjVHSldqUTlRbGY1anJfTDJNWDM0NWFLZ0l5NVZZfm9nWnBoTWdqZw%3D%3D&nonce=UlRrbnRpOFFZcXJHVllIOH5VNk1sTUUtTEpOM0F0RXg4Y2VRaEN2d0JjUg%3D%3D&code_challenge=03VHmwHDV56Tz7Wpe8qQtZEb_y692NueGqhmSyeJ4Ls&code_challenge_method=S256&auth0Client={AUTH0_CLIENT}

Note: I have not tested with the sample app at this point in time

auth0-react version

2.2.1

React version

18.2

Which browsers have you tested in?

Chrome, Other

Hi @ian-weir

It looks like you're passing an array as your authorizationParams in prod

new URLSearchParams({ client_id: 'foo', ...'foobar'.split('') }).toString();
// '0=f&1=o&2=o&3=b&4=a&5=r&client_id=foo'

I'd need to see some code that reproduces the issue if you want me to debug it for you

Hi @adamjmcgrath as far as I can tell, I'm not passing an array anywhere.

Here's the snippet that handles the loginWithRedirect for invitations

const authorizationParams: AppState  = {
    organization: params.get('organization'),
    redirect_uri: `${baseUrl.current}/callback`
}

if(params.get('invitation')) {
  authorizationParams.invitation = params.get('invitation')
}

await loginWithRedirect({
  authorizationParams,
  appState: {
    returnTo: '/users/user/get-current-user-id/dashboard'
  }
})

and here's the one that handles when the user clicks our login button:

const organizationInHostname = hostname.current.split('.')[0]
const authorizationParams: AppState = {
  redirect_uri: `${baseUrl.current}/callback`,
}

if(organizationInHostname !== 'login') {
  authorizationParams.organization = organizationInHostname
}

await loginWithRedirect({
  authorizationParams,
  appState: {
    returnTo: '/users/user/get-current-user-id/dashboard'
  }
})

While this is the Provider

<Auth0Provider
  domain={domain}
  clientId={clientId}
  authorizationParams={{
    audience
  }}
  onRedirectCallback={onRedirectCallback}
  useRefreshTokens={true}
  cookieDomain={cookieDomain.current}
  cacheLocation="localstorage"
>

Just an update I was able to work around this by manually appending the query params in the openUrl method

Hi @ian-weir

Could you log authorizationParams before you call loginWithRedirect in production mode and share the result?

Sure thing: {invitation: "foo", organization: "bar", redirect_uri: "http://localhost:3000/callback"}

Here's the resulting URL: https://dev-ws8z8uiswqyyrcam.us.auth0.com/authorize?0=U&1=z&2=l&3=V&4=Z&5=E&6=R&7=Y&8=V&9=W&10=M&11=t&12=V&13=0&14=F&15=l&16=Q&17=m&18=R&19=u&20=T&21=m&22=p&23=y&24=T&25=k&26=F&27=P&28=S&29=k&30=9&31=v&32=V&33=W&34=Z&35=o&36=Q&37=m&38=8&39=4&40=S&41=m&42=t&43=o&44=N&45=1&46=9&47=Y&48=X&49=0&50=Q&51=0&52=R&53=2&54=1&55=W&56=U&57=w&58=%3D&59=%3D&client_id={CLIENT_ID}&scope=openid+profile+email+offline_access&audience={AUDIENCE}&response_type=code&response_mode=query&state=UzlVZERYVWMtV0FlQmRuTmpyTkFPSk9vVWZoQm84SmtoN19YX0Q0R21WUw%3D%3D&nonce=MzI2YzF2VWdmM2tNZDFYZWthbGo4YUJUcWU5SE9VRV80MnMwV1pMNWdBeA%3D%3D&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&code_challenge=rfTPyK0X8mO9g1nXL-KQ70spNRLq95vsaDSgZ51QZHw&code_challenge_method=S256&auth0Client={AUTH0_CLIENT}

Hi @ian-weir - thanks for sharing those

When I call

await loginWithRedirect({
  authorizationParams: {invitation: "foo", organization: "bar", redirect_uri: "http://localhost:3000/callback"}
})

I get redirected to .../authorize?redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&invitation=foo&organization=bar&response_type=code&...

So can't reproduce your issue.

In order to help you - I'll need a repo or a link that demonstrates the issue.

Closing because no more information was provided. Feel free to provide a reproduction if you need further assistance and we can reopen as needed.

Sorry, spaced on this thread. Unfortunately I can't give a repo as it's for work and we're not open source. As for link I can't do that for now either as we haven't launched yet. @adamjmcgrath Out of curiosity what version of React, Next, & auth0-react were you using?

For me:

auth0-react version - 2.2.1
React version - 18.2
Next version - 13.3.2