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

HTTP: 400 on authenticate with missing refresh-token when devMode=false (refresh-token not persisted correctly) #44

Open
Oyveloper opened this issue Jan 8, 2025 · 6 comments

Comments

@Oyveloper
Copy link

We recently set up auth-kit-react with TanStack (i.e. fully client side), following the instructions on https://workos.com/docs/user-management/client-only/2-add-authkit-to-your-app

Locally, all is fine as devMode is True, and refresh-token is stored in local storage.
When deploying the site however, we get a 400 error whenever auth-kit tries to reauthenticate, as it does not pass the refresh-token.

However, setting devMode true works well also in production.

Anyone got an idea why the prod setup does not work in our case?

Our test-setup to debug:

import { Outlet, createRootRoute, useNavigate } from '@tanstack/react-router';
import { AuthKitProvider } from '@workos-inc/authkit-react';
import { useEffect, useState } from 'react';
import { useLocation } from '@tanstack/react-router';
import { useAuth } from '@workos-inc/authkit-react';


function ProviderWrapper() {
  const [redirect, setRedirect] = useState<{ returnTo: string; search: any } | null>(null);
  const navigate = useNavigate();

  useEffect(() => {
    if (redirect) {
      navigate({ to: redirect.returnTo, search: redirect.search });
    }
  }, [redirect]);

  return (
    <>
      <AuthKitProvider
        clientId={getEnvVar('WORKOS_CLIENT_ID')}
        redirectUri={getWorkosRedirectURI()}
        onRedirectCallback={({ state }) => {
          if (state?.returnTo) {
            setRedirect({ returnTo: state.returnTo, search: state.search });
          }
        }}
      >
        <ShortcutProvider>
          <RecoilRoot>
            <Root />
          </RecoilRoot>
        </ShortcutProvider>
      </AuthKitProvider>
    </>
  );
}

export default function useUser() {
  const { user, getAccessToken, isLoading, signIn } = useAuth();
  const location = useLocation();

  useEffect(() => {
    if (!isLoading && !user) {
      signIn({ state: { returnTo: location.pathname + '/', search: location.search } });
    }
  }, [isLoading, user]);


  return { user, isLoading, getAccessToken };
}


function Root() {
  const { user, isLoading, getAccessToken } = useUser();
  if (isLoading || !user) return <FullScreenSpinner />;

  return <>Hello world</>;

}
@cmatheson
Copy link
Collaborator

@Oyveloper I'll push up a fix for the instructions you referenced. You must pass apiHostname to AuthKitProvider in order for the cookie to get set properly for production mode (see the example in the README).

@Oyveloper
Copy link
Author

ok, so apiHostname should be the domain for our backend api?. The way we read the README this should be the auth domain, which in our case is workos:

apiHostname: Defaults to api.workos.com. This should be set to your custom Authentication API domain in production.

@cmatheson
Copy link
Collaborator

@Oyveloper it should be your auth domain, but you need a custom auth domain so that the session cookie can be set properly. If you don't have a custom domain, just keep devMode={true} on your <AuthKitProvider>

@Oyveloper
Copy link
Author

Hmm ok, perhaps the devMode field should be named differently, if it is a viable strategy to run in production with devMode={true}?
Or should we simply put the default authKit Domain that we can see in the workos dashboard (i.e. random-string.authkit.app)?

@cmatheson
Copy link
Collaborator

@Oyveloper we don't recommend running in devMode in production. Having the refresh token in local storage is less secure than the httponly cookie (this might be an acceptable amount of risk for your app).

You won't be able to use the authkit.app domain (it's not an API endpoint, and also 3rd party cookie blocking will prevent the cookie from being set properly).

Our recommendation for SPAs is to register a custom domain with WorkOS and use that as your apiHostname.

@Oyveloper
Copy link
Author

So you say we need to pay the $99/month for custom domain in order to use the more secure option?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants