fix(loader): skip Express session middleware on loader backends#192
Merged
jameswillis99 merged 1 commit intomasterfrom Mar 20, 2026
Merged
fix(loader): skip Express session middleware on loader backends#192jameswillis99 merged 1 commit intomasterfrom
jameswillis99 merged 1 commit intomasterfrom
Conversation
The Express session middleware (express-session + passport.session()) was registered globally and fired on every request, including all loader endpoints (/api/v1/loader/*, /static/js/loader-hydrate*). This caused two problems: 1. Set-Cookie: connect.sid=... on CDN-cached responses. CloudFront/Fastly stores response headers on cache-miss and replays them on cache-hits. All users receiving a cached loader response were getting the session cookie from the original request. Versioned endpoints have a 1yr TTL, so this cookie was replayed for a very long time. The cookie is low-risk (empty anonymous session, no auth state), but is unintended pollution of public CDN responses. 2. Unnecessary DB work per request. passport.session() calls deserializeUser() on every request, which issues a DB query to hydrate req.user. Loader routes authenticate exclusively via x-plasmic-api-project-tokens / x-plasmic-api-token headers (handled by apiAuth). They have zero references to req.session or req.user -- the DB lookup was pure waste on every loader request. Fix: pass skipSession: true to createApp() in loader-backend.ts and loader-html-backend.ts. Both are dedicated backends that serve only loader routes. The skipSession path already exists in createApp() and is used by tests. Studio (app-backend-real.ts) is unchanged -- it still needs session for login/logout and all authenticated Studio routes. Closes plasmic-terraservices#11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Express session middleware (express-session + passport.session()) was registered globally and fired on every request, including all loader endpoints (/api/v1/loader/, /static/js/loader-hydrate).
This caused two problems:
Set-Cookie: connect.sid=... on CDN-cached responses. CloudFront/Fastly stores response headers on cache-miss and replays them on cache-hits. All users receiving a cached loader response were getting the session cookie from the original request. Versioned endpoints have a 1yr TTL, so this cookie was replayed for a very long time. The cookie is low-risk (empty anonymous session, no auth state), but is unintended pollution of public CDN responses.
Unnecessary DB work per request. passport.session() calls deserializeUser() on every request, which issues a DB query to hydrate req.user. Loader routes authenticate exclusively via x-plasmic-api-project-tokens / x-plasmic-api-token headers (handled by apiAuth). They have zero references to req.session or req.user -- the DB lookup was pure waste on every loader request.
Fix: pass skipSession: true to createApp() in loader-backend.ts and loader-html-backend.ts. Both are dedicated backends that serve only loader routes. The skipSession path already exists in createApp() and is used by tests.
Studio (app-backend-real.ts) is unchanged -- it still needs session for login/logout and all authenticated Studio routes.
Closes plasmic-terraservices#11