Skip to content

Commit a5e9529

Browse files
fix(backend): Do not cache 307 redirects (#4171)
Co-authored-by: Stefanos Anagnostou <anagstef@users.noreply.github.com>
1 parent 4a9f6d8 commit a5e9529

File tree

6 files changed

+42
-18
lines changed

6 files changed

+42
-18
lines changed

.changeset/spotty-students-judge.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@clerk/backend": patch
3+
---
4+
5+
Fix Chrome caching 307 redirects when a handshake is triggered.

package-lock.json

+22-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/backend/src/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const Headers = {
5555
ContentType: 'content-type',
5656
SecFetchDest: 'sec-fetch-dest',
5757
Location: 'location',
58+
CacheControl: 'cache-control',
5859
} as const;
5960

6061
const ContentTypes = {

packages/backend/src/tokens/__tests__/request.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ function assertHandshake(
6262
signInUrl?: string;
6363
},
6464
) {
65+
assert.true(!!requestState.headers.get('cache-control'));
6566
assert.propContains(requestState, {
6667
proxyUrl: '',
6768
status: AuthStatus.Handshake,

packages/backend/src/tokens/request.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export async function authenticateRequest(
9696
url.searchParams.append(constants.QueryParameters.DevBrowser, authenticateContext.devBrowserToken);
9797
}
9898

99-
return new Headers({ location: url.href });
99+
return new Headers({ [constants.Headers.Location]: url.href });
100100
}
101101

102102
async function resolveHandshake() {
@@ -120,7 +120,8 @@ export async function authenticateRequest(
120120
const newUrl = new URL(authenticateContext.clerkUrl);
121121
newUrl.searchParams.delete(constants.QueryParameters.Handshake);
122122
newUrl.searchParams.delete(constants.QueryParameters.HandshakeHelp);
123-
headers.append('Location', newUrl.toString());
123+
headers.append(constants.Headers.Location, newUrl.toString());
124+
headers.set(constants.Headers.CacheControl, 'no-store');
124125
}
125126

126127
if (sessionToken === '') {
@@ -174,6 +175,13 @@ ${error.getFullMessage()}`,
174175
// Right now the only usage of passing in different headers is for multi-domain sync, which redirects somewhere else.
175176
// In the future if we want to decorate the handshake redirect with additional headers per call we need to tweak this logic.
176177
const handshakeHeaders = headers ?? buildRedirectToHandshake();
178+
179+
// Chrome aggressively caches inactive tabs. If we don't set the header here,
180+
// all 307 redirects will be cached and the handshake will end up in an infinite loop.
181+
if (handshakeHeaders.get(constants.Headers.Location)) {
182+
handshakeHeaders.set(constants.Headers.CacheControl, 'no-store');
183+
}
184+
177185
// Introduce the mechanism to protect for infinite handshake redirect loops
178186
// using a cookie and returning true if it's infinite redirect loop or false if we can
179187
// proceed with triggering handshake.
@@ -294,7 +302,7 @@ ${error.getFullMessage()}`,
294302
authenticateContext.clerkUrl.toString(),
295303
);
296304

297-
const headers = new Headers({ location: redirectURL.toString() });
305+
const headers = new Headers({ [constants.Headers.Location]: redirectURL.toString() });
298306
return handleMaybeHandshakeStatus(authenticateContext, AuthErrorReason.SatelliteCookieNeedsSyncing, '', headers);
299307
}
300308

@@ -314,7 +322,7 @@ ${error.getFullMessage()}`,
314322
}
315323
redirectBackToSatelliteUrl.searchParams.append(constants.QueryParameters.ClerkSynced, 'true');
316324

317-
const headers = new Headers({ location: redirectBackToSatelliteUrl.toString() });
325+
const headers = new Headers({ [constants.Headers.Location]: redirectBackToSatelliteUrl.toString() });
318326
return handleMaybeHandshakeStatus(authenticateContext, AuthErrorReason.PrimaryRespondsToSyncing, '', headers);
319327
}
320328
/**

packages/fastify/src/__tests__/__snapshots__/constants.test.ts.snap

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ exports[`constants from environment variables 1`] = `
1919
"AuthStatus": "x-clerk-auth-status",
2020
"AuthToken": "x-clerk-auth-token",
2121
"Authorization": "authorization",
22+
"CacheControl": "cache-control",
2223
"ClerkRedirectTo": "x-clerk-redirect-to",
2324
"ClerkRequestData": "x-clerk-request-data",
2425
"ClerkUrl": "x-clerk-clerk-url",

0 commit comments

Comments
 (0)