Cache handling recommendation for authentication handshake redirects

Hi Netlify team! Rob from Clerk here. I’m just curious if there’s a recommended way of fixing our issue here.

Description

We’re encountering redirect loops with Clerk’s authentication handshake mechanism with Netlify’s caching, specifically in server-rendered applications. Here’s the sequence that causes the issue:

  1. User lands on the app (e.g., https://some-app.netlify.app/)
  2. Server immediately returns a 307 redirect to FAPI to start the handshake flow and determine auth state
  3. FAPI verifies auth state, issues new session token, and redirects back to original URL
  4. Instead of getting fresh auth check, Netlify serves the cached response from step 2
  5. This creates an infinite loop as the cached response contains the same handshake redirect logic

Current Workaround

We implemented a temporary solution in our Astro middleware that specifically targets Netlify environments:

function handleNetlifyCacheInDevInstance(locationHeader: string, requestState: RequestState) {
  // Only run on Netlify environment and Clerk development instance
  if (import.meta.env.NETLIFY && isDevelopmentFromPublishableKey(requestState.publishableKey)) {
    const hasHandshakeQueryParam = locationHeader.includes('__clerk_handshake');
    
    // If location header is the original URL before the handshake redirects, add cache bust param
    if (!hasHandshakeQueryParam) {
      const url = new URL(locationHeader);
      url.searchParams.append(NETLIFY_CACHE_BUST_PARAM, Date.now().toString());
      requestState.headers.set('Location', url.toString());
    }
  }
}

This solution:

  1. Adds a timestamp-based cache bust parameter to the initial redirect
  2. Only applies to Netlify environments
  3. Prevents the cache hit while maintaining Netlify’s caching benefits for other routes

We want to add this fix to more of our SDKs (tanstack-start, nuxt, etc.). For some reason, this issue doesn’t seem to appear in Next and OpenNext.

Questions/Recommendations:

  1. Is there a more standardized way to handle auth redirect flows with your caching system?
  2. Could there be a header or directive that marks certain responses as “auth-sensitive” to prevent caching?

Thank you very much for your time!

Where is this token stored? Cookie? Headers? Query params? The docs you linked mostly mention Cookies, but fair disclaimer, I didn’t go through it in detail. In any case, it looks like you simply need to add the correct netlify-vary response headers: Caching | Netlify Docs. Have you tried that?

Thanks for the quick response! The tokens are indeed stored in cookies.

I think I checked the caching docs before but not in detail re: netlify-vary. I’ll try and add that headers on the redirects:

const requestState = await clerkClient.authenticateRequest(clerkRequest)

requestState.headers.set('Netlify-Vary', 'cookie=__client|__session')
return new Response(null, { status: 307, headers: requestState.headers })

or if you have a suggestion. I appreciate it!

I don’t. Basically, you need to vary the cache on the params you need to be varied. In your case if you need a different variation of cache for the __client and __session cookies, the code you’ve used seems to be correct.