Auto-switch to a valid session when the current session is revoked with the multi-session plugin #1903

Closed
opened 2026-03-13 09:11:47 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @Maxime-RiseVerse on GitHub (Sep 11, 2025).

Is this suited for github?

  • Yes, this is suited for github

When using the multi-session plugin together with single-device-per-email enforcement, users get fully logged out on a device even if other valid sessions exist in the same browser.

Example scenario

  • Device A: Logged in with accounts A, B, C
  • Device B: Account B logs in and triggers revokeOtherSessions()
  • Device A: B’s session is revoked. Instead of switching to A or C, getSession returns null and the user is logged out

The additional multi-session cookies created by the plugin remain in the browser, but there is no supported way to promote one of them to the active session at this point, so they are effectively orphaned.

Describe the solution you'd like

Handle this natively inside Better Auth. When getSession determines that the current session is invalid or revoked:

  1. Check for multi-session cookies set by the plugin
  2. Validate those tokens against the database
  3. Promote a valid one to become the main session cookie using the library’s own signing and expected format
  4. Continue the request with the recovered session instead of returning null

This provides a seamless experience similar to apps like Gmail or Slack, where losing one account does not sign the user out of the others.

Possible API shapes:

  • Multi-session plugin option: autoSwitchOnInvalid: true
  • Core toggle: session.autoRecoverFromMultiSession: true
  • Internal step during getSession to verify available multi-session tokens and promote one safely

Describe alternatives you've considered

  1. Manual cookie swap in a before hook. It switched sessions, but later broke logout and account switching due to signature checks.

  2. Server-side multiSession.setActive() in a hook. Timing issue: after revocation, there is no valid session cookie, so the call cannot authenticate.

  3. Using Better Auth cookie setters in hooks. Timing and format issue: you would have to mint the main session cookie yourself, which is not supported.

  4. Client-side authClient.multiSession.setActive(). Same timing issue as above. Once the main session is gone, the request is not authenticated.

  5. After-hook recovery. Timing issue: it runs after validation failed, so you would need a redirect and still cannot safely mint the main session cookie.

Additional context

This is a common UX pattern for multi-account apps. With single-device-per-email policies, users currently experience unnecessary logouts even when other valid sessions are present. Native auto-recovery would make the multi-session plugin significantly more useful.

Originally created by @Maxime-RiseVerse on GitHub (Sep 11, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### Is your feature request related to a problem? Please describe. When using the multi-session plugin together with single-device-per-email enforcement, users get fully logged out on a device even if other valid sessions exist in the same browser. Example scenario - Device A: Logged in with accounts A, B, C - Device B: Account B logs in and triggers revokeOtherSessions() - Device A: B’s session is revoked. Instead of switching to A or C, getSession returns null and the user is logged out The additional multi-session cookies created by the plugin remain in the browser, but there is no supported way to promote one of them to the active session at this point, so they are effectively orphaned. ### Describe the solution you'd like Handle this natively inside Better Auth. When getSession determines that the current session is invalid or revoked: 1. Check for multi-session cookies set by the plugin 3. Validate those tokens against the database 5. Promote a valid one to become the main session cookie using the library’s own signing and expected format 7. Continue the request with the recovered session instead of returning null This provides a seamless experience similar to apps like Gmail or Slack, where losing one account does not sign the user out of the others. Possible API shapes: - Multi-session plugin option: autoSwitchOnInvalid: true - Core toggle: session.autoRecoverFromMultiSession: true - Internal step during getSession to verify available multi-session tokens and promote one safely ### Describe alternatives you've considered 1. Manual cookie swap in a before hook. It switched sessions, but later broke logout and account switching due to signature checks. 2. Server-side multiSession.setActive() in a hook. Timing issue: after revocation, there is no valid session cookie, so the call cannot authenticate. 3. Using Better Auth cookie setters in hooks. Timing and format issue: you would have to mint the main session cookie yourself, which is not supported. 4. Client-side authClient.multiSession.setActive(). Same timing issue as above. Once the main session is gone, the request is not authenticated. 5. After-hook recovery. Timing issue: it runs after validation failed, so you would need a redirect and still cannot safely mint the main session cookie. ### Additional context This is a common UX pattern for multi-account apps. With single-device-per-email policies, users currently experience unnecessary logouts even when other valid sessions are present. Native auto-recovery would make the multi-session plugin significantly more useful.
GiteaMirror added the enhancement label 2026-03-13 09:11:47 -05:00
Author
Owner

@Maxime-RiseVerse commented on GitHub (Sep 11, 2025):

@dosu What do you think?

@Maxime-RiseVerse commented on GitHub (Sep 11, 2025): @dosu What do you think?
Author
Owner

@dosubot[bot] commented on GitHub (Sep 11, 2025):

Your proposal makes a lot of sense and aligns with UX patterns in other multi-account apps. Right now, Better Auth doesn't natively auto-switch to another valid session if the main session is revoked—getSession just returns null and logs the user out, even if other multi-session cookies are present. The multi-session plugin does have logic to promote another session cookie, but only inside specific plugin endpoints (like revokeDeviceSession), not in the core session flow or getSession itself. So, your suggested feature would fill a real gap and improve the multi-session experience significantly.

From a technical perspective, it's feasible: the plugin already knows how to validate and promote multi-session cookies, so extending this logic to getSession (optionally, via a toggle like autoSwitchOnInvalid or session.autoRecoverFromMultiSession) is possible. The main things to consider are security (making sure only valid, non-expired sessions are promoted and that there's no risk of session fixation or hijacking) and user clarity (making sure the user understands which account is now active after a switch).

Edge cases to watch for: session expiration, device fingerprinting (if used), and making sure the fallback doesn't accidentally promote a stale or revoked session. But overall, your API suggestions and flow are solid and would fit well with the current plugin architecture. This would be a strong candidate for a core or plugin-level enhancement.

If you want to prototype, the logic in the multi-session plugin's revokeDeviceSession endpoint is a good starting point for how to scan and promote valid multi-session cookies automatically.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 11, 2025): <!-- Answer --> Your proposal makes a lot of sense and aligns with UX patterns in other multi-account apps. Right now, Better Auth doesn't natively auto-switch to another valid session if the main session is revoked—getSession just returns null and logs the user out, even if other multi-session cookies are present. The multi-session plugin does have logic to promote another session cookie, but only inside specific plugin endpoints (like revokeDeviceSession), not in the core session flow or getSession itself. So, your suggested feature would fill a real gap and improve the multi-session experience significantly. From a technical perspective, it's feasible: the plugin already knows how to validate and promote multi-session cookies, so extending this logic to getSession (optionally, via a toggle like autoSwitchOnInvalid or session.autoRecoverFromMultiSession) is possible. The main things to consider are security (making sure only valid, non-expired sessions are promoted and that there's no risk of session fixation or hijacking) and user clarity (making sure the user understands which account is now active after a switch). Edge cases to watch for: session expiration, device fingerprinting (if used), and making sure the fallback doesn't accidentally promote a stale or revoked session. But overall, your API suggestions and flow are solid and would fit well with the current plugin architecture. This would be a strong candidate for a core or plugin-level enhancement. If you want to prototype, the logic in the multi-session plugin's revokeDeviceSession endpoint is a good starting point for how to scan and promote valid multi-session cookies automatically. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/670225ab-d512-4ad2-a451-6bf7fc709ef6?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/670225ab-d512-4ad2-a451-6bf7fc709ef6?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/670225ab-d512-4ad2-a451-6bf7fc709ef6?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/670225ab-d512-4ad2-a451-6bf7fc709ef6?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/670225ab-d512-4ad2-a451-6bf7fc709ef6?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/670225ab-d512-4ad2-a451-6bf7fc709ef6?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/670225ab-d512-4ad2-a451-6bf7fc709ef6?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4585)
Author
Owner

@Maxime-RiseVerse commented on GitHub (Sep 11, 2025):

@dosu thanks. If I’m not wrong, this isn’t doable today without a change:

  • The multi-session endpoints (list/setActive/revoke) require a valid session cookie; after revocation there isn’t one.
  • Hooks can set signed cookies, but they cannot safely create the main session cookie. Its format and signing are internal, and manual attempts break later flows.
  • After hooks run after validation, so I would have to set a cookie and redirect. That adds a round trip and still does not solve the main-cookie creation.

If there is a supported server-side way to promote a multi-session cookie without an active session, please point me to it.

@Maxime-RiseVerse commented on GitHub (Sep 11, 2025): @dosu thanks. If I’m not wrong, this isn’t doable today without a change: - The multi-session endpoints (list/setActive/revoke) require a valid session cookie; after revocation there isn’t one. - Hooks can set signed cookies, but they cannot safely create the main session cookie. Its format and signing are internal, and manual attempts break later flows. - After hooks run after validation, so I would have to set a cookie and redirect. That adds a round trip and still does not solve the main-cookie creation. If there is a supported server-side way to promote a multi-session cookie without an active session, please point me to it.
Author
Owner

@dosubot[bot] commented on GitHub (Sep 11, 2025):

You're correct—there isn't a supported server-side way today to promote a multi-session cookie to the main session without an active session cookie. The only documented approaches for minting a main session cookie server-side require either the returnHeaders option during sign-in or manually signing a session token with internal helpers and the secret, but these methods assume you already have a valid session token and don't address the multi-session promotion flow after revocation. Manual attempts to set the main session cookie from a multi-session token aren't supported and can break downstream flows due to internal format and signature requirements. A code or API change would be needed to enable this natively—there's no built-in or documented workaround for your use case right now. Reference

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 11, 2025): <!-- Answer --> You're correct—there isn't a supported server-side way today to promote a multi-session cookie to the main session without an active session cookie. The only documented approaches for minting a main session cookie server-side require either the returnHeaders option during sign-in or manually signing a session token with internal helpers and the secret, but these methods assume you already have a valid session token and don't address the multi-session promotion flow after revocation. Manual attempts to set the main session cookie from a multi-session token aren't supported and can break downstream flows due to internal format and signature requirements. A code or API change would be needed to enable this natively—there's no built-in or documented workaround for your use case right now. [Reference](https://github.com/better-auth/better-auth/issues/3851) <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/f59a2a6f-7d08-411f-acd6-d607ee31533b?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/f59a2a6f-7d08-411f-acd6-d607ee31533b?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/f59a2a6f-7d08-411f-acd6-d607ee31533b?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/f59a2a6f-7d08-411f-acd6-d607ee31533b?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/f59a2a6f-7d08-411f-acd6-d607ee31533b?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/f59a2a6f-7d08-411f-acd6-d607ee31533b?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/f59a2a6f-7d08-411f-acd6-d607ee31533b?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4585)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1903