WCAG 2.2.5: Re-authenticating
WCAG 2.2.5 Re-authenticating (Level AA): Restore Session Without Data Loss
WCAG 2.2.5 Re-authenticating is a critical success criterion introduced in WCAG 2.1, rated at Level AA. Its primary goal is to ensure that when a user’s authenticated session expires and they are required to re-authenticate, they can resume their activity exactly where they left off, without losing any previously entered data or settings. This criterion addresses a common source of frustration and inaccessibility on the web, particularly for users engaged in complex or time-consuming tasks.
Why This Criterion Matters
The ability to re-authenticate and continue an activity without data loss is fundamental for an accessible and user-friendly experience. Losing data due to a session timeout can have significant negative impacts, especially for certain user groups:
- Users with Cognitive Disabilities: Individuals with memory impairments, attention deficit disorders, or other cognitive disabilities may find it incredibly difficult or impossible to remember and re-enter lost data. The frustration of starting over can lead to abandonment of tasks.
- Users with Limited Dexterity: Typing or navigating complex forms can be physically challenging and time-consuming. Losing progress means repeating arduous actions, which can be painful and deter users from completing their tasks.
- Screen Reader Users: Re-entering data requires a screen reader user to navigate through the form again, re-identify fields, and re-input information, which can be a slow and error-prone process. Losing context also forces them to reorient themselves within the application.
- Users with Low Vision: Similarly, users who rely on magnifiers or other assistive technologies may have difficulty re-finding their place and accurately re-entering data after an unexpected interruption.
- Users Using Speech Input: Dictating extensive text or navigating intricate forms using speech can be tiring. Losing data forces them to repeat these exhausting processes.
In essence, this criterion minimizes unnecessary effort, reduces cognitive load, and prevents user frustration, making web applications more robust and inclusive for everyone.
Success Criterion and Requirements
The WCAG 2.2.5 Re-authenticating (Level AA) success criterion states:
When an authenticated session expires, the user can re-authenticate and continue activity without loss of data or settings of that activity.
Exceptions:
There are specific situations where this criterion does not apply:
- Where the activity is a real-time event: For example, an ongoing live auction or a multiplayer game where the state is constantly changing and cannot reasonably be paused or restored to a previous specific point.
- Where all data for the activity is automatically saved by the system: If the application automatically saves all user input and progress server-side, and can seamlessly restore it upon re-authentication, then no data is lost.
- Where the user has not interacted with the activity during the authenticated session: If a user simply logged in and left their session idle without performing any actions, there is no ‘activity’ or ‘data’ to lose.
- Where the user has explicitly requested to clear data or log out: If the user intentionally ends their session or clears their data, then data loss is expected and desired.
- Where loss of data is essential to the security of the activity: For extremely sensitive activities (e.g., banking transactions involving transferring funds), security protocols might mandate that a session must be completely reset upon re-authentication to prevent certain types of attacks. This exception should be used judiciously and only when truly necessary for security.
Practical Guidelines for Compliance
Achieving compliance with WCAG 2.2.5 involves implementing strategies that preserve user data and context across session boundaries. This typically involves a combination of server-side and client-side techniques.
1. Server-Side Session Management:
- Store Partial Data: For multi-step forms or complex workflows, save user input to the database or server-side session storage at each step, or periodically via AJAX requests. Associate this data with the user’s ID.
- Maintain Context: When a user re-authenticates, redirect them to the exact page or step they were on, rather than the homepage or a generic dashboard.
- Pre-fill Forms: Use the stored data to pre-populate form fields after re-authentication.
2. Client-Side Data Preservation (for temporary or less critical data):
- Local Storage/Session Storage: Use browser’s `localStorage` or `sessionStorage` to temporarily save form field values, user preferences, or current progress. This can be used to re-populate fields quickly if a timeout occurs before server-side saving. Remember that `localStorage` persists across browser sessions, while `sessionStorage` is cleared when the browser tab is closed.
- Autosave: Implement autosave functionality using JavaScript to periodically save user input to `localStorage` or via AJAX to the server.
3. User Notification and Session Extension:
- Timely Warnings: Provide clear, accessible warnings before a session is about to expire, giving users enough time to extend their session or save their work.
- Extend Session Option: Offer a simple way for users to extend their session (e.g., a “Keep me logged in” button within the warning dialog).
Examples of Correct and Incorrect Implementations
Correct Implementation: Multi-Step Form with Session Restoration
In this example, user input from a multi-step form is saved using `localStorage` on the client-side. Upon re-authentication, this data is used to pre-fill the form, and the user is redirected to their last known step.
HTML (Part of a multi-step form)
<!-- Step 1 of 3: User Details -->
<form id="userDetailsForm">
<label for="firstName">First Name:</label>
<input type="text" id="firstName" name="firstName">
<br>
<label for="lastName">Last Name:</label>
<input type="text" id="lastName" name="lastName">
<br>
<button type="button" onclick="saveAndProceed(1)">Next Step</button>
</form>
<!-- (Assume similar forms for Step 2 and Step 3 on different pages/views) -->
JavaScript (Client-side logic)
function saveFormProgress(step) {
const formData = {};
document.querySelectorAll(`#userDetailsForm input, #userDetailsForm textarea, #userDetailsForm select`).forEach(element => {
formData[element.name] = element.value;
});
localStorage.setItem(`form_step_${step}_data`, JSON.stringify(formData));
localStorage.setItem('last_form_step', step);
}
function loadFormProgress(step) {
const storedData = localStorage.getItem(`form_step_${step}_data`);
if (storedData) {
const formData = JSON.parse(storedData);
for (const name in formData) {
const element = document.querySelector(`[name="${name}"]`);
if (element) {
element.value = formData[name];
}
}
}
}
function saveAndProceed(currentStep) {
saveFormProgress(currentStep);
// Simulate server-side save and navigation to next step
console.log(`Saved data for step ${currentStep}. Proceeding to next step.`);
// In a real app, this would involve a server call and redirect
// For demonstration, let's just update the stored step
const nextStep = currentStep + 1;
if (nextStep <= 3) {
localStorage.setItem('last_form_step', nextStep);
// Redirect or load next part of the form
window.location.href = `/application/step${nextStep}`;
} else {
console.log('Form complete!');
localStorage.removeItem('last_form_step');
}
}
// On page load or after re-authentication
window.onload = function() {
const lastStep = localStorage.getItem('last_form_step');
if (lastStep && window.location.pathname.includes(`/application/step${lastStep}`)) {
loadFormProgress(lastStep);
} else if (!lastStep && window.location.pathname === '/application/step1') {
loadFormProgress(1); // Load for first step if no progress found
}
// Simulate re-authentication logic (this would be handled server-side)
// If user session expired and re-authenticated, they are redirected to '/application/stepX'
// and this script ensures the form is pre-filled.
};
// Server-side (simplified concept):
// If user session expires, they are redirected to a login page.
// After successful login, the server checks the 'last_form_step' from a persistent server-side record
// (or client-side local storage if passed securely) and redirects to `/application/stepX`.
// The client-side JS then automatically pre-fills the form.
Incorrect Implementation: Data Loss on Re-authentication
In this scenario, a user fills out a substantial form. Their session expires, they are redirected to the login page, and upon successful re-authentication, they are taken back to an empty form or the application’s homepage, losing all their previously entered data.
Scenario Description:
A user is filling out a detailed support request form with multiple text areas and file uploads. After spending 15 minutes drafting their issue, their session times out. They are redirected to the login page. Upon logging back in, they are sent to the application’s dashboard. Navigating back to the support request form, they find all fields are empty, and their drafted message is gone.
Problematic Code/Logic (Conceptual):
// Server-side logic when session expires
app.use((req, res, next) => {
if (!req.session.user && req.isAuthenticated()) {
// Session expired, user still logged in in browser but not server session
// Force re-login
return res.redirect('/login?returnTo=' + req.originalUrl);
} else if (!req.isAuthenticated()) {
// Not authenticated at all
return res.redirect('/login?returnTo=' + req.originalUrl);
}
next();
});
// Login POST handler
app.post('/login', passport.authenticate('local', {
successRedirect: '/dashboard', // Always redirects to dashboard after login
failureRedirect: '/login'
}));
// When user accesses '/support-request' after re-login
app.get('/support-request', (req, res) => {
// No server-side or client-side logic to retrieve previous form data
res.render('support-request-form', { formData: {} }); // Renders an empty form
});
Best Practices and Common Pitfalls
Best Practices:
- Robust Server-Side Session Management: Prioritize storing critical user input and workflow state on the server, linked to the user’s account, allowing for robust restoration even if the client-side data is lost.
- Client-Side Autosave/Local Storage: Implement client-side solutions like `localStorage` for quick recovery of unsaved changes, particularly in dynamic forms or content editors. Ensure this is used in conjunction with server-side persistence for full reliability.
- Clear Session Expiration Warnings: Notify users well in advance (e.g., 5 minutes before timeout) with an accessible modal or banner, offering a clear option to extend their session.
- Contextual Redirects: After re-authentication, always redirect the user to the precise page, view, or even scroll position they were on before the timeout, and pre-fill any available data.
- “Remember Me” Functionality: For less sensitive applications, offer a “Remember Me” option that extends the login session for a longer period, reducing the frequency of re-authentication.
- Handle File Uploads: If file uploads are part of the process, ensure these are either persisted server-side immediately or cached securely on the client so they don’t need to be re-uploaded.
- Graceful Error Handling: If data restoration fails for any reason, provide helpful messages rather than simply presenting an empty page.
Common Pitfalls:
- Relying Solely on Client-Side State: While `localStorage` is useful, it’s not a complete solution. It can be cleared by users, browsers, or browser extensions, leading to data loss. Server-side persistence is essential for reliable data recovery.
- Forcing Users to Restart Complex Tasks: Redirecting to the homepage or a blank form after re-authentication is a major pitfall that leads to high user frustration and abandonment.
- Inadequate Timeout Warnings: Providing no warning, or a warning that is too short, doesn’t give users enough time to react and save their work or extend their session.
- Generic Login Redirects: Sending all users to a generic login page or dashboard without considering their previous context.
- Not Handling Exceptions Properly: Misinterpreting the “security essential” exception can lead to unnecessary data loss for users when other secure methods could have preserved their data.
- Ignoring Edge Cases: What happens if the user’s browser crashes during re-authentication? What if there’s a network issue? Robust solutions consider these scenarios.
Conclusion
WCAG 2.2.5 Re-authenticating is about respect for the user’s time and effort. By implementing strategies that preserve data and context across authenticated sessions, developers and designers can create more robust, user-friendly, and inclusive web applications that truly support all users, regardless of their abilities or circumstances. Adherence to this criterion significantly enhances the overall accessibility and usability of authenticated web experiences.