#WorkOS logouts on refresh in production

4 messages · Page 1 of 1 (latest)

keen stone
#

The WorkOS coponent seems to be working nicely on localhost, but in production when I refresh the page, I immediately get logged out. Why is this happening and how can it be fixed

devout fogBOT
#

Hi @keen stone. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

This issue often occurs due to a mismatch between how WorkOS and Convex handle token validation, or a race condition during the initial load in production environments. Based on the knowledge sources, here are the most likely causes and solutions:

1. Missing aud (Audience) Claim

In production, Convex requires the aud (audience) claim in the JWT to match your WorkOS Client ID. If this is missing or incorrectly configured, Convex will fail to validate the token.

  • Fix: Ensure your WorkOS Dashboard JWT configuration has the audience claim set to your Client ID [Discord support thread].
  • Alternative: If you are using the OIDC-style integration, ensure your convex/auth.config.ts matches your production domain and Client ID [WorkOS Authkit Integration].

2. Authentication Race Condition

A common issue in production (especially with Next.js or Vite) is that the application briefly enters an Unauthenticated or Loading state while the WorkOS SDK is initializing. This can cause components to unmount or the client to think the user is logged out before the token is actually fetched [WorkOS Authkit Integration].

The Fix: Update your useAuthFromAuthKit hook (or equivalent) to ensure isLoading is true until the accessToken is actually present:

function useAuthFromAuthKit() {
  const { user, loading: isUserLoading } = useAuth();
  const { accessToken, loading: tokenLoading, error: tokenError } = useAccessToken();
#

// Ensure loading is true until we have an actual accessToken
const loading = isUserLoading || tokenLoading || (!!user && !accessToken && !tokenError);
const authenticated = !!user && !!accessToken;

return {
isLoading: loading,
isAuthenticated: authenticated,
fetchAccessToken: async () => accessToken ?? null,
};
}

Adding `|| !accessToken` to your loading logic helps prevent "flash" logouts during the initial refresh [[WorkOS Authkit Integration](<https://discord.com/channels/1019350475847499849/1202520608672317471>)].

### 3. Missing `WORKOS_COOKIE_PASSWORD`
WorkOS AuthKit requires a secure cookie password (at least 32 characters) to encrypt session cookies in production. If this is missing or too short in your production environment variables, sessions will not persist across refreshes [[Convex & WorkOS AuthKit Docs](<https://docs.convex.dev/auth/authkit/#configuring-dev-and-prod-instances>)].
*   **Fix:** Generate a key using `openssl rand -base64 24` and set it as `WORKOS_COOKIE_PASSWORD` in your production environment (e.g., Vercel) [[Convex & WorkOS AuthKit Docs](<https://docs.convex.dev/auth/authkit/#configuring-dev-and-prod-instances>)].

### 4. Use `getAccessToken` for Freshness
If you are seeing logouts after some time or on specific refreshes, use the `getAccessToken` function from the WorkOS SDK instead of relying on a static reference. This function is designed to handle refreshes automatically and guarantee a fresh token for Convex [[WorkOS Authkit Integration](<https://discord.com/channels/1019350475847499849/1202520608672317471>)].
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------