Bird
Raised Fist0
NextJSframework~20 mins

Role-based access patterns in NextJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Role-Based Access Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What will this Next.js component render for a user with role 'editor'?

Consider this Next.js functional component that shows different content based on user roles.

import { useState } from 'react';

export default function Dashboard() {
  const [userRole] = useState('editor');

  if (userRole === 'admin') {
    return <h1>Admin Panel</h1>;
  } else if (userRole === 'editor') {
    return <h1>Editor Workspace</h1>;
  } else {
    return <h1>Viewer Page</h1>;
  }
}
NextJS
import { useState } from 'react';

export default function Dashboard() {
  const [userRole] = useState('editor');

  if (userRole === 'admin') {
    return <h1>Admin Panel</h1>;
  } else if (userRole === 'editor') {
    return <h1>Editor Workspace</h1>;
  } else {
    return <h1>Viewer Page</h1>;
  }
}
A<h1>Editor Workspace</h1>
B<h1>Admin Panel</h1>
C<h1>Viewer Page</h1>
DComponent throws an error
Attempts:
2 left
💡 Hint

Check the value of userRole and which condition matches.

state_output
intermediate
2:00remaining
What is the value of accessLevel after this code runs?

Given this React state update in a Next.js component, what will accessLevel be?

import { useState } from 'react';

export default function AccessControl() {
  const [role] = useState('guest');
  const [accessLevel, setAccessLevel] = useState('none');

  if (role === 'admin') {
    setAccessLevel('full');
  } else if (role === 'editor') {
    setAccessLevel('partial');
  } else {
    setAccessLevel('read-only');
  }

  return <div>Access: {accessLevel}</div>;
}
NextJS
import { useState } from 'react';

export default function AccessControl() {
  const [role] = useState('guest');
  const [accessLevel, setAccessLevel] = useState('none');

  if (role === 'admin') {
    setAccessLevel('full');
  } else if (role === 'editor') {
    setAccessLevel('partial');
  } else {
    setAccessLevel('read-only');
  }

  return <div>Access: {accessLevel}</div>;
}
AAccess: none
BComponent causes infinite loop
CAccess: full
DAccess: read-only
Attempts:
2 left
💡 Hint

Think about what happens when you call setAccessLevel inside the component body.

📝 Syntax
advanced
2:00remaining
Which option correctly implements role-based access using Next.js middleware?

Choose the correct Next.js middleware code snippet that restricts access to '/admin' pages only to users with role 'admin'.

A
export function middleware(request) {
  const role = request.cookies.get('role');
  if (role !== 'admin') {
    return Response.redirect('/login');
  }
  return NextResponse.next();
}
B
export function middleware(request) {
  const role = request.cookies.get('role');
  if (role !== 'admin') {
    return NextResponse.redirect('/login', 302);
  }
  return NextResponse.next();
}
C
export function middleware(request) {
  const role = request.cookies.get('role');
  if (role !== 'admin') {
    return redirect('/login');
  }
  return NextResponse.next();
}
D
import { NextResponse } from 'next/server';

export function middleware(request) {
  const role = request.cookies.get('role');
  if (role !== 'admin') {
    return NextResponse.redirect('/login');
  }
  return NextResponse.next();
}
Attempts:
2 left
💡 Hint

Check the correct usage of Next.js NextResponse.redirect method.

🔧 Debug
advanced
2:00remaining
Why does this role check fail to protect the page?

Examine this Next.js page component that tries to restrict access to admins only. Why does it fail?

export default function AdminPage({ user }) {
  if (user.role !== 'admin') {
    return <p>Access Denied</p>;
  }
  return <h1>Welcome Admin</h1>;
}

export async function getServerSideProps(context) {
  const user = await getUserFromSession(context.req);
  return { props: { user } };
}
NextJS
export default function AdminPage({ user }) {
  if (user.role !== 'admin') {
    return <p>Access Denied</p>;
  }
  return <h1>Welcome Admin</h1>;
}

export async function getServerSideProps(context) {
  const user = await getUserFromSession(context.req);
  return { props: { user } };
}
AThe component does not redirect unauthorized users, so they still see the page content.
BThe role check is case-sensitive and user.role is 'Admin' with uppercase A, so the check fails.
CThe user object is undefined because getUserFromSession returns null for unauthenticated users, causing a runtime error.
DgetServerSideProps does not run on the server, so user data is missing.
Attempts:
2 left
💡 Hint

Consider what happens if user is null or undefined.

🧠 Conceptual
expert
3:00remaining
Which approach best secures role-based access in a Next.js app?

Choose the most secure and scalable approach to enforce role-based access control in a Next.js application.

AImplement role checks in API routes and server-side rendering functions, returning 403 or redirecting unauthorized users.
BUse client-side role checks in React components only, hiding UI elements based on user role stored in local state.
CStore user roles in cookies and rely on client-side JavaScript to block access to pages by checking cookie values.
DUse static site generation with role-based content filtering at build time to serve different pages per role.
Attempts:
2 left
💡 Hint

Think about where security checks must happen to prevent unauthorized access.

Practice

(1/5)
1. What is the main purpose of role-based access control in a Next.js application?
easy
A. To improve the app's loading speed by caching user data
B. To restrict or allow users to see or perform actions based on their assigned roles
C. To style components differently for each user
D. To automatically generate user profiles

Solution

  1. Step 1: Understand role-based access control concept

    Role-based access control means controlling what users can do or see based on their roles.
  2. Step 2: Identify the purpose in Next.js apps

    In Next.js, this means showing or hiding parts of the app depending on user roles to protect sensitive data.
  3. Final Answer:

    To restrict or allow users to see or perform actions based on their assigned roles -> Option B
  4. Quick Check:

    Role-based access controls user permissions = B [OK]
Hint: Role-based access controls user permissions and visibility [OK]
Common Mistakes:
  • Confusing access control with styling or caching
  • Thinking it automatically creates user profiles
  • Assuming it improves app speed
2. Which of the following is the correct way to check a user's role in a Next.js component using session data?
easy
A. if (session.user.role === 'admin') { /* allow access */ }
B. if (user.role == 'admin') { /* allow access */ }
C. if (session.role === 'admin') { /* allow access */ }
D. if (session.user.roles.includes('admin')) { /* allow access */ }

Solution

  1. Step 1: Identify session structure in Next.js

    Session data usually stores user info under session.user, including role as session.user.role.
  2. Step 2: Check correct syntax for role comparison

    The correct check is session.user.role === 'admin' to compare role string exactly.
  3. Final Answer:

    if (session.user.role === 'admin') { /* allow access */ } -> Option A
  4. Quick Check:

    Use session.user.role for role check = C [OK]
Hint: Access role via session.user.role for correct check [OK]
Common Mistakes:
  • Using user.role without session prefix
  • Checking session.role directly (wrong path)
  • Using == instead of === for strict comparison
  • Assuming roles is an array when it's a string
3. Given this Next.js code snippet, what will be rendered if the user role is 'editor'?
function Dashboard({ session }) {
  if (session.user.role === 'admin') {
    return <div>Admin Panel</div>;
  } else if (session.user.role === 'editor') {
    return <div>Editor Workspace</div>;
  } else {
    return <div>Access Denied</div>;
  }
}
medium
A. Nothing will render due to error
B. <div>Admin Panel</div>
C. <div>Access Denied</div>
D. <div>Editor Workspace</div>

Solution

  1. Step 1: Check user role conditionals

    The code checks if role is 'admin', then 'editor', else denies access.
  2. Step 2: Match role 'editor' to conditional

    Since role is 'editor', the second condition matches and returns <div>Editor Workspace</div>.
  3. Final Answer:

    <div>Editor Workspace</div> -> Option D
  4. Quick Check:

    Role 'editor' matches editor condition = A [OK]
Hint: Match user role to if-else branches to find output [OK]
Common Mistakes:
  • Choosing admin panel for editor role
  • Assuming access denied for editor
  • Thinking code has syntax errors
4. Identify the error in this Next.js role check code snippet:
function Page({ session }) {
  if (session.user.role = 'admin') {
    return <div>Admin Access</div>;
  }
  return <div>No Access</div>;
}
medium
A. session.user.role should be session.role
B. Missing else block after if statement
C. Using single equals (=) instead of triple equals (===) for comparison
D. Return statements are not allowed inside if

Solution

  1. Step 1: Check the if condition syntax

    The code uses single equals (=) which assigns value instead of comparing.
  2. Step 2: Identify correct comparison operator

    For comparison, triple equals (===) should be used to check equality without assignment.
  3. Final Answer:

    Using single equals (=) instead of triple equals (===) for comparison -> Option C
  4. Quick Check:

    Use === for comparison, not = [OK]
Hint: Use === for comparison, not = assignment [OK]
Common Mistakes:
  • Confusing assignment (=) with comparison (===)
  • Thinking else block is mandatory
  • Incorrect session property path assumptions
  • Believing return inside if is invalid
5. You want to protect a Next.js API route so only users with role 'admin' or 'manager' can access it. Which code snippet correctly implements this role-based access check?
hard
A. if (['admin', 'manager'].includes(session.user.role)) { /* allow */ } else { /* deny */ }
B. if (session.user.role === ['admin', 'manager']) { /* allow */ } else { /* deny */ }
C. if (session.user.role == 'admin' && session.user.role == 'manager') { /* allow */ } else { /* deny */ }
D. if (session.user.role === 'admin' && session.user.role === 'manager') { /* allow */ } else { /* deny */ }

Solution

  1. Step 1: Understand role check for multiple roles

    We want to allow access if role is either 'admin' or 'manager'.
  2. Step 2: Evaluate each option's logic

    if (session.user.role === 'admin' && session.user.role === 'manager') { /* allow */ } else { /* deny */ } uses && which requires the role to be both simultaneously (impossible); if (session.user.role === ['admin', 'manager']) { /* allow */ } else { /* deny */ } compares role to array directly (wrong); if (['admin', 'manager'].includes(session.user.role)) { /* allow */ } else { /* deny */ } uses includes() on array which is clean and correct; if (session.user.role == 'admin' && session.user.role == 'manager') { /* allow */ } else { /* deny */ } uses && which requires role to be both roles simultaneously (impossible).
  3. Final Answer:

    if (['admin', 'manager'].includes(session.user.role)) { /* allow */ } else { /* deny */ } -> Option A
  4. Quick Check:

    Use includes() to check multiple roles = D [OK]
Hint: Use array.includes(role) to check multiple roles easily [OK]
Common Mistakes:
  • Comparing role directly to an array
  • Using && instead of || for multiple roles
  • Not using includes() for clean checks
  • Assuming || is always better than includes()