-
Notifications
You must be signed in to change notification settings - Fork 8
Description
When using authkit-react with devMode={false}, refreshing the browser on a protected route (e.g., /convo/some-id) causes an incorrect redirection flow. Instead of returning the user to the original protected route (/convo/some-id) after authentication, the user is ultimately redirected to /login and then often to the root (/). This behaviour does not occur when devMode={true}.
The issue seems related to the handling of the state parameter passed to signIn and retrieved in the onRedirectCallback. Debugging suggests the initial state correctly contains the returnTo path, but after the redirect back from WorkOS to the redirectUri (/login in this case), the state available to onRedirectCallback or subsequent logic appears incorrect or lost, preventing the intended redirect back to the original protected route.
Steps to Reproduce
- Configure AuthKitProvider with a valid clientId, redirectUri (e.g., /login), and crucially, devMode={false}.
- Implement a mechanism to protect routes, such as the useUser hook provided below, which calls signIn if the user is not authenticated.
- Set up a login page (/login) that handles the redirect from WorkOS (using signIn({ context }) if necessary) and redirects logged-in users away (e.g., to /).
- Log in to the application successfully.
- Navigate to a protected route that is not the root path (e.g., /convo/some-id).
- Refresh the browser page (F5 / Cmd+R).
- Observe the redirection flow.
Expected behavior
After refreshing the page on /convo/some-id:
- The useUser hook detects no user initially and calls signIn({ state: { returnTo: '/convo/some-id' } }).
- The user is redirected to the WorkOS Hosted UI (may happen instantaneously if already authenticated with WorkOS).
- WorkOS redirects the user back to the redirectUri (/login in this case) with an authorization code and the original state.
- AuthKitProvider processes the redirect.
- The onRedirectCallback is invoked with the original state, containing { returnTo: '/convo/some-id' }.
- The callback navigates the user to /convo/some-id.
Actual behavior
After refreshing the page on /convo/some-id:
- The useUser hook detects no user and calls signIn({ state: { returnTo: '/convo/some-id' } }). (Confirmed via logs)
- User is redirected to WorkOS and back to /login?code=....
- AuthKitProvider processes the redirect.
- The onRedirectCallback either doesn't receive the correct state or subsequent logic interferes. Debugging suggests the state retrieved at this point might be incorrect (e.g., potentially reflecting /login instead of the original returnTo).
- The logic in the /login page might then execute (e.g., the if (user) check) because the intended redirect didn't happen immediately or correctly, causing a final redirect to /.
CC @nicknisi