Skip to content

Commit

Permalink
Fix auth issue where session token and publicData cookie were updated…
Browse files Browse the repository at this point in the history
… unnecessarily, leading to potential user logout (#3556)

* fix auth issue where session token and public data token was updated unnecessarily
  • Loading branch information
flybayer authored Jul 18, 2022
1 parent abe2afc commit 8bcb471
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 17 deletions.
9 changes: 9 additions & 0 deletions .changeset/sour-lemons-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@blitzjs/auth": patch
"blitz": patch
---

Fix auth issue where session token and publicData cookie were updated unnecessarily, leading to potential user logout

- Previously, we were updating the session token each time public data changed. This is not needed, and it would cause race condition bugs where a user could be unexpectedly logged out because a request already in flight would not match the new session token.
- Previously, we were updating the publicData cookie even when it hadn't changed. This may reduce unnecessary re-renders on the client.
20 changes: 3 additions & 17 deletions packages/blitz-auth/src/server/auth-sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -801,30 +801,16 @@ async function refreshSession(
const expiresAt = addYears(new Date(), 30)
setAnonymousSessionCookie(req, res, anonymousSessionToken, expiresAt)
setPublicDataCookie(req, res, publicDataToken, expiresAt)
setCSRFCookie(req, res, sessionKernel.antiCSRFToken, expiresAt)
} else if (global.sessionConfig.method === "essential" && "sessionToken" in sessionKernel) {
const expiresAt = addMinutes(new Date(), global.sessionConfig.sessionExpiryMinutes as number)
const publicDataToken = createPublicDataToken(sessionKernel.publicData)

let sessionToken: string
// Only generate new session token if public data actually changed
// Otherwise if new session token is generated just for refresh, then
// we have race condition bugs
if (publicDataChanged) {
sessionToken = createSessionToken(sessionKernel.handle, sessionKernel.publicData)
} else {
sessionToken = sessionKernel.sessionToken
}

setSessionCookie(req, res, sessionToken, expiresAt)
setPublicDataCookie(req, res, publicDataToken, expiresAt)
setCSRFCookie(req, res, sessionKernel.antiCSRFToken, expiresAt)

debug("Updating session in db with", {expiresAt})
if (publicDataChanged) {
debug("Public data has changed")
const publicDataToken = createPublicDataToken(sessionKernel.publicData)
setPublicDataCookie(req, res, publicDataToken, expiresAt)
await global.sessionConfig.updateSession(sessionKernel.handle, {
expiresAt,
hashedSessionToken: hash256(sessionToken),
publicData: JSON.stringify(sessionKernel.publicData),
})
} else {
Expand Down

0 comments on commit 8bcb471

Please sign in to comment.