Page Authentication and Access Control Flow
Overview
In our application, every page follows a consistent authentication and access control pattern designed to ensure secure and controlled user interactions. This documentation explains the standard flow implemented across all pages.
Authentication Stages
1. User Authentication
Every page begins with a critical authentication check:
const Nextcookies = await cookies();
const user = getUserFromCookie(Nextcookies.get('user')?.value);
This step retrieves the user's authentication information from cookies. If no user is found, access is immediately denied:
if (!user) {
return <AccessDenied errorMessage="Not logged in" />;
}
The getUserFromCookie function is responsible for parsing the cookie and returning valid user details. If the cookie is missing or invalid, the user will not be authenticated.
2. Long-Term User Restriction
After initial authentication, pages check if the user is a long-term user:
if (isLongTerm(user.sid)) {
return <AccessDenied />;
}
This step enforces business logic to restrict access for certain user types based on session ID classification.
3. Feedback Completion Check
After validating the user and ensuring they are not a long-term user, the system checks whether the user has completed a specific task:
const hasAlreadyDoneTot = await checkFeedback(
user.sid,
user.pin,
'check_hybrid_feedback'
);
If the user has not completed the task, they are prompted for confirmation using:
AutoOpenConfirmation
checkFeedback ensures users complete prerequisite workflows before proceeding to page content.
Key Utility Functions
getUserFromCookie()
- Purpose: Decodes and validates user information from the authentication cookie.
- Returns:
- A user object with critical details like
sidandpinif the cookie is valid. nullif the cookie is invalid or expired.
- A user object with critical details like
isLongTerm(sid)
- Purpose: Determines if a user is a "long-term" user based on their session ID.
- Use Case: Implements specific business logic to classify user types.
checkFeedback(sid, pin, task)
- Purpose: Checks if a user has completed a specific task.
- Parameters:
sid: Session ID.pin: User’s personal identification number.task: The identifier for the specific task to check.
- Returns: A boolean indicating task completion.
The task parameter, such as 'check_hybrid_feedback', determines the type of feedback to validate.
Access Denial Handling
The <AccessDenied> component serves two primary purposes:
- Displaying a user-friendly error message.
- Preventing unauthorized access to sensitive pages.
Custom Error Messages
You can provide custom error messages to give users more context about why access was denied:
return <AccessDenied errorMessage="Login required" />;
Custom error messages help improve user experience by clarifying access issues.
Best Practices
- Always perform authentication server-side.
- Use server components for sensitive routes.
- Validate user permissions at multiple levels.
- Provide clear, informative access denial messages.
Server-side authentication and layered access control ensure defense in depth against unauthorized access.
Example Implementation
export default async function RestrictedPage() {
const user = await authenticateUser();
// Early return if not authenticated
if (!user) {
return <AccessDenied message="Login required" />;
}
// Additional access control
if (isLongTerm(user.sid)) {
return <AccessDenied message="Restricted access" />;
}
// Feedback completion check
const hasAlreadyDoneTot = await checkFeedback(
user.sid,
user.pin,
'check_hybrid_feedback'
);
if (!hasAlreadyDoneTot) {
return <AutoOpenConfirmation />;
}
// Page content for authorized users
return <PageContent user={user} />;
}
Security Considerations
- Always validate authentication and access server-side to prevent client-side manipulation.
- Use defense-in-depth strategies, including multiple layers of access control.
- Verify user sessions with each page load to prevent session hijacking.
Customization Points
getUserFromCookie(): Update to change cookie parsing logic.isLongTerm(): Adjust for different user classification rules.checkFeedback(): Modify logic for validating task completion.<AccessDenied>and<AutoOpenConfirmation>: Customize for branding and improved user experience.
Customizing these components allows for tailored user workflows while maintaining security and clarity.