Skip to main content
Operable WCAG 2.2.5

2.2.5 Re-authenticating

When an authenticated session expires, the user can continue the activity without loss of data after re-authenticating.

Level AAA Moderate WCAG 2.0 (new) WCAG 2.1 WCAG 2.2

What this rule means

WCAG 2.2.5 requires that when an authenticated session expires and the user must re-authenticate (log in again), the application preserves all data and state from before the session expired. After logging back in, the user should be returned to exactly where they were, with all form data, selections, and progress intact.

This does not prevent sessions from expiring — security requirements may necessitate timeouts. However, it ensures that session expiration does not punish users by destroying their work. The application must save the user's state server-side or client-side before the session expires and restore it after re-authentication.

Why it matters

Users with disabilities often take significantly longer to complete tasks. A blind user filling out a complex form may take 30-60 minutes using a screen reader. If the session expires at minute 45 and all form data is lost, the user must start over — potentially losing an hour of careful work. This disproportionately affects disabled users who need more time.

Even for users without disabilities, losing data after a session timeout is frustrating and erodes trust. For users with cognitive disabilities, having to remember and re-enter information after an interruption may be exceptionally difficult. Preserving state across re-authentication ensures continuity and respects the user's investment of time and effort.

Related axe-core rules

There are no automated axe-core rules for this criterion. Session management and data preservation are server-side concerns that cannot be detected through client-side DOM analysis. Manual testing across session expiration boundaries is required.

How to test

Testing requires triggering session expiration during various tasks and verifying data preservation.

  1. Begin filling out a form or performing a multi-step task while authenticated.
  2. Wait for the session to expire (or manually expire it through developer tools or server configuration).
  3. Re-authenticate (log back in).
  4. Verify that all previously entered form data, selections, scroll position, and task progress are restored.
  5. Test across different types of activities: forms, file uploads, multi-step wizards, content editing.
  • Verify that the user is redirected to the same page and context they were on before the session expired.

How to fix

Implement state preservation that saves user progress before or during session expiration.

Auto-save with session restoration

// Save form state periodically and before session expires
function autoSaveFormState(formId) {
  const form = document.getElementById(formId);
  const formData = new FormData(form);
  const state = Object.fromEntries(formData.entries());

  // Save to server (associated with user account)
  fetch('/api/save-draft', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      formId,
      state,
      url: window.location.href,
      scrollPosition: window.scrollY
    })
  });
}

// Auto-save every 30 seconds
setInterval(() => autoSaveFormState('main-form'), 30000);

// Save on visibility change (user switches tabs)
document.addEventListener('visibilitychange', () => {
  if (document.hidden) autoSaveFormState('main-form');
});

Restore state after re-authentication

// After successful login, check for saved state
async function onLoginSuccess(userId) {
  const response = await fetch(
    `/api/restore-draft?userId=${userId}`
  );
  const draft = await response.json();

  if (draft && draft.url) {
    // Redirect to the page they were on
    sessionStorage.setItem('restore-draft', JSON.stringify(draft));
    window.location.href = draft.url;
  }
}

// On page load, restore the draft if it exists
window.addEventListener('load', () => {
  const draft = sessionStorage.getItem('restore-draft');
  if (draft) {
    const { state, scrollPosition } = JSON.parse(draft);
    restoreFormData(state);
    window.scrollTo(0, scrollPosition);
    sessionStorage.removeItem('restore-draft');
    showNotification('Your previous progress has been restored.');
  }
});

Common mistakes

  • Session expiration that redirects to the login page and then to the homepage instead of the original page.
  • Saving form state in sessionStorage only — this is cleared when the browser tab is closed.
  • Not saving state for multi-step wizards, losing the user's position in a workflow.
  • Restoring form inputs but not restoring file upload selections, which require re-uploading.
  • Not informing the user that their progress has been saved and will be restored after re-authentication.
  • Only preserving state for the most recent page, not for complex multi-tab workflows.

Resources