Fixing Inconsistent Session Timeout Behavior: A Deep Dive

by ADMIN 58 views

Hey guys! Today, we're diving deep into a tricky bug we've encountered: inconsistent session timeout behavior. This is a major pain for users, so let's get into the nitty-gritty and see how we can squash it.

The Problem: Unpredictable Session Expiry

Session timeout issues can be incredibly frustrating for users. Imagine working on something important, only to be abruptly logged out and lose your progress. That's the situation we're dealing with, and we need to fix it ASAP.

The core problem is that session timeouts aren't behaving as expected. We've configured a 30-day inactivity timeout, but users are reporting wildly different experiences. Some are getting logged out within hours, while others have sessions that persist far beyond the 30-day limit. To add to the chaos, there's no warning system in place before a session expires, making the experience even more jarring.

Why is this happening? There could be a multitude of reasons, and the bug report highlights several key areas to investigate. It seems like the LastSeenAt timestamp, which should track user activity, isn't consistently updating. This means the system can't accurately determine when a session should expire. The SessionAutoRevocationService, responsible for revoking inactive sessions, might also be malfunctioning. On the frontend, the lack of a session validity check and warning system exacerbates the problem. Identifying the root cause is crucial, and will likely involve digging into both the backend and frontend code.

The impact of this bug is significant. Users are losing data and experiencing a poor user experience. This not only creates frustration but also erodes trust in the application. A reliable session management system is fundamental to any web application, especially one dealing with user data and sensitive operations. Fixing this inconsistency is therefore a top priority. We need to ensure that sessions expire predictably and that users are given ample warning before being logged out. This requires a comprehensive approach, addressing the backend logic, the frontend implementation, and the communication between the two.

Steps to Reproduce the Bug

To really understand the issue, we need to be able to reproduce it consistently. Here are a couple of scenarios that have been reported:

  1. Scenario 1: Random Logouts:
    • Log in with valid credentials.
    • Perform various API operations (upload a file, query data, etc.).
    • Leave the browser tab open for 8-12 hours.
    • Return and try to interact with the application. Sometimes you'll be immediately logged out, and sometimes the session persists.
  2. Scenario 2: Sessions Persisting Too Long:
    • Log in and actively use the application.
    • Close the browser without logging out.
    • Reopen the browser after 35+ days. The session is still active, even though it should have been revoked after 30 days.

These steps help us narrow down the problem and provide a starting point for debugging. It's important to try these steps ourselves and see if we can replicate the inconsistent behavior. This hands-on experience is invaluable in understanding the bug's nuances and developing an effective fix.

Expected vs. Actual Behavior

Let's clarify what should be happening versus what is actually happening. This helps us define the scope of the problem and the goals of our solution.

Expected Behavior:

  • Sessions should consistently timeout after 30 days of inactivity.
  • The LastSeenAt timestamp should update with every authenticated API request.
  • The SessionAutoRevocationService should reliably revoke inactive sessions every hour.
  • The frontend should check session validity periodically (every 5 minutes).
  • Users should receive a warning modal 5 minutes before session expiry.
  • The warning modal should include a "Stay Logged In" button to extend the session.
  • After expiry, users should be gracefully redirected to the login page with a clear explanation.
  • Session state should be synchronized between the backend and frontend.

Actual Behavior:

  • Sessions expire unpredictably, sometimes within hours despite activity.
  • Sessions persist beyond the configured 30-day timeout.
  • No warning is given before session expiry.
  • Users lose their work when unexpectedly logged out.
  • LastSeenAt might not be updating consistently on all API requests.
  • The frontend has no mechanism to detect impending session expiry.

The discrepancy between expected and actual behavior highlights the severity of the bug. We're not just dealing with a minor inconvenience; we have a fundamental issue with session management that needs to be addressed comprehensively. The lack of warning messages, the inconsistent timeouts, and the potential for data loss all contribute to a frustrating user experience. Our goal is to bring the actual behavior in line with the expected behavior, creating a secure and reliable session management system.

Environment Details

Knowing the environment is crucial for effective debugging. Here’s the setup we're working with:

  • Backend: ASP.NET Core 9.0 (.NET 9)
  • Frontend: Next.js 14 (React 18)
  • Database: PostgreSQL
  • Cache: Redis
  • Configuration:
    • Authentication:SessionManagement:InactivityTimeoutDays = 30
    • Authentication:SessionManagement:AutoRevocationIntervalHours = 1

These details tell us a lot about the technologies involved and where potential issues might lie. For example, the backend being on ASP.NET Core 9.0 means we need to look at the session management features and configurations specific to that framework. The frontend using Next.js 14 and React 18 suggests we should examine how session state is being managed and persisted on the client-side. The use of PostgreSQL as a database and Redis as a cache points to areas where session data might be stored and retrieved.

The configuration settings are particularly important. InactivityTimeoutDays = 30 is the core of our expected behavior, so we need to ensure this setting is being correctly applied throughout the system. AutoRevocationIntervalHours = 1 indicates how frequently the backend should be checking for and revoking inactive sessions. Understanding these environmental factors helps us formulate targeted debugging strategies.

Acceptance Criteria: Defining Success

To ensure we've truly fixed the bug, we need clear acceptance criteria. These are the specific conditions that must be met before we can consider the issue resolved.

Backend Acceptance Criteria:

  • [ ] Session timeout configured consistently in appsettings.json and applied correctly.
  • [ ] SessionAutoRevocationService reliably revokes sessions after 30 days inactivity.
  • [ ] LastSeenAt timestamp updated on EVERY authenticated API request (verify middleware).
  • [ ] Add endpoint GET /api/v1/auth/session/status returning: `{