Skip to content

Commit ffdf6ea

Browse files
committed
feat(backend): Use __clerk_suffixed_cookies cookie to ask suffixed cookies in handshake
1 parent 731aae4 commit ffdf6ea

File tree

4 files changed

+12
-29
lines changed

4 files changed

+12
-29
lines changed

packages/backend/src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const Cookies = {
1919
ClientUat: '__client_uat',
2020
Handshake: '__clerk_handshake',
2121
DevBrowser: '__clerk_db_jwt',
22+
SuffixedCookies: '__clerk_suffixed_cookies',
2223
} as const;
2324

2425
const QueryParameters = {

packages/backend/src/tokens/authenticateContext.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ interface AuthenticateContextInterface extends AuthenticateRequestOptions {
1919
// cookie-based values
2020
sessionTokenInCookie: string | undefined;
2121
clientUat: number;
22+
suffixedCookies: boolean;
2223
// handshake-related values
2324
devBrowserToken: string | undefined;
2425
handshakeToken: string | undefined;
@@ -95,6 +96,7 @@ class AuthenticateContext {
9596
private initCookieValues() {
9697
this.sessionTokenInCookie = this.getMultipleAppsCookie(constants.Cookies.Session);
9798
this.clientUat = Number.parseInt(this.getMultipleAppsCookie(constants.Cookies.ClientUat) || '') || 0;
99+
this.suffixedCookies = this.getMultipleAppsCookie(constants.Cookies.SuffixedCookies) === 'true';
98100
}
99101

100102
private stripAuthorizationHeader(authValue: string | undefined | null): string | undefined {

packages/backend/src/tokens/cookie.ts

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,7 @@
1-
const getCookieName = (cookieDirective: string): string => {
1+
export const getCookieName = (cookieDirective: string): string => {
22
return cookieDirective.split(';')[0]?.split('=')[0];
33
};
44

5-
const getSuffixedName = (name: string, suffix: string): string => {
6-
if (name.endsWith(suffix)) {
7-
return name;
8-
}
9-
return `${name}_${suffix}`;
10-
};
11-
12-
export const suffixCookie = (suffix: string, cookieDirective: string): string => {
13-
const name = getCookieName(cookieDirective);
14-
const suffixedName = getSuffixedName(name, suffix);
15-
16-
return cookieDirective.replace(name + '=', suffixedName + '=');
17-
};
18-
19-
export const unSuffixCookie = (suffix: string, cookieDirective: string): string => {
20-
const name = getCookieName(cookieDirective).replace('_' + suffix, '');
21-
const suffixedName = getSuffixedName(suffix, cookieDirective);
22-
return cookieDirective.replace(suffixedName + '=', name + '=');
5+
export const getCookieValue = (cookieDirective: string): string => {
6+
return cookieDirective.split(';')[0]?.split('=')[1];
237
};

packages/backend/src/tokens/request.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import type { TokenCarrier } from '../errors';
33
import { TokenVerificationError, TokenVerificationErrorReason } from '../errors';
44
import { decodeJwt } from '../jwt/verifyJwt';
55
import { assertValidSecretKey } from '../util/optionsAssertions';
6-
import { getCookieSuffix, isDevelopmentFromSecretKey } from '../util/shared';
6+
import { isDevelopmentFromSecretKey } from '../util/shared';
77
import type { AuthenticateContext } from './authenticateContext';
88
import { createAuthenticateContext } from './authenticateContext';
99
import type { RequestState } from './authStatus';
1010
import { AuthErrorReason, handshake, signedIn, signedOut } from './authStatus';
1111
import { createClerkRequest } from './clerkRequest';
12-
import { suffixCookie, unSuffixCookie } from './cookie';
12+
import { getCookieName, getCookieValue } from './cookie';
1313
import { verifyHandshakeToken } from './handshake';
1414
import type { AuthenticateRequestOptions } from './types';
1515
import { verifyToken } from './verify';
@@ -89,7 +89,7 @@ export async function authenticateRequest(
8989

9090
const url = new URL(`https://${frontendApiNoProtocol}/v1/client/handshake`);
9191
url.searchParams.append('redirect_url', redirectUrl?.href || '');
92-
url.searchParams.append('suffixed_cookies', 'true');
92+
url.searchParams.append('suffixed_cookies', authenticateContext.suffixedCookies.toString());
9393

9494
if (authenticateContext.instanceType === 'development' && authenticateContext.devBrowserToken) {
9595
url.searchParams.append(constants.QueryParameters.DevBrowser, authenticateContext.devBrowserToken);
@@ -106,16 +106,12 @@ export async function authenticateRequest(
106106

107107
const handshakePayload = await verifyHandshakeToken(authenticateContext.handshakeToken!, authenticateContext);
108108
const cookiesToSet = handshakePayload.handshake;
109-
const cookieSuffix = getCookieSuffix(authenticateContext.publishableKey);
110109

111110
let sessionToken = '';
112111
cookiesToSet.forEach((x: string) => {
113-
const suffixedCookie = suffixCookie(cookieSuffix, x);
114-
headers.append('Set-Cookie', suffixedCookie);
115-
const unSuffixedCookie = unSuffixCookie(cookieSuffix, x);
116-
headers.append('Set-Cookie', unSuffixedCookie);
117-
if (unSuffixedCookie.startsWith(`${constants.Cookies.Session}=`)) {
118-
sessionToken = unSuffixedCookie.split(';')[0].substring(10);
112+
headers.append('Set-Cookie', x);
113+
if (getCookieName(x).startsWith(constants.Cookies.Session)) {
114+
sessionToken = getCookieValue(x);
119115
}
120116
});
121117

0 commit comments

Comments
 (0)