Bird
Raised Fist0
NestJSframework~20 mins

Protected routes with guards in NestJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
NestJS Guard Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What happens when a request is made to a route protected by a guard that returns false?

Consider a NestJS route protected by a guard. The guard's canActivate method returns false. What will be the result when a client tries to access this route?

NestJS
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    return false;
  }
}

// Controller snippet
@Get('protected')
@UseGuards(AuthGuard)
getProtected() {
  return 'Protected content';
}
AThe request is denied and the client receives a 403 Forbidden response.
BThe request proceeds and the client receives 'Protected content'.
CThe server throws an internal server error (500).
DThe guard is ignored and the route behaves as if unprotected.
Attempts:
2 left
💡 Hint

Think about what returning false from canActivate means for route access.

📝 Syntax
intermediate
2:00remaining
Which option correctly implements a guard that allows access only if a request header 'x-api-key' equals 'secret'?

Choose the correct NestJS guard implementation that checks if the request header x-api-key equals secret. If it matches, access is allowed; otherwise, denied.

A
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class ApiKeyGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return request.headers.xApiKey === 'secret';
  }
}
B
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class ApiKeyGuard implements CanActivate {
  canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest();
    if (request.headers['x-api-key'] === 'secret') {
      return true;
    }
    return false;
  }
}
C
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class ApiKeyGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return request.headers['X-API-KEY'] === 'secret';
  }
}
D
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class ApiKeyGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return request.headers['x-api-key'] === 'secret';
  }
}
Attempts:
2 left
💡 Hint

Remember that HTTP headers are case-insensitive but usually accessed in lowercase in Node.js.

🔧 Debug
advanced
2:00remaining
Why does this guard always allow access even when the token is missing?

Examine the following guard code. It is intended to deny access if the authorization header is missing. However, it always allows access. What is the cause?

NestJS
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class TokenGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    if (!request.headers.authorization) {
      return false;
    }
    return true;
  }
}
AThe guard throws a syntax error due to missing return in the if block.
BThe guard returns undefined causing NestJS to allow access by default.
CThe guard always returns true because the if block does not return false explicitly.
DThe guard returns false but the route is still accessible due to misconfiguration.
Attempts:
2 left
💡 Hint

Look carefully at the if block and what it returns.

❓ state_output
advanced
2:00remaining
What is the output when a guard throws an exception inside canActivate?

Consider a guard that throws a ForbiddenException inside its canActivate method. What will the client receive when accessing the protected route?

NestJS
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';

@Injectable()
export class ExceptionGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    throw new ForbiddenException('Access denied');
  }
}

// Controller snippet
@Get('secret')
@UseGuards(ExceptionGuard)
getSecret() {
  return 'Secret data';
}
AThe client receives a 403 Forbidden response with message 'Access denied'.
BThe client receives a 500 Internal Server Error response.
CThe client receives 'Secret data' because exceptions are ignored.
DThe server crashes and stops responding.
Attempts:
2 left
💡 Hint

Think about how NestJS handles exceptions thrown in guards.

🧠 Conceptual
expert
2:00remaining
Which statement about NestJS guards and route protection is TRUE?

Choose the correct statement about how NestJS guards protect routes.

AGuards run after route handlers and can modify the response before sending.
BMultiple guards can be applied to a route and all must return true to allow access.
CGuards can only be applied at the controller level, not on individual routes.
DIf a guard returns a Promise that resolves to false, NestJS treats it as true.
Attempts:
2 left
💡 Hint

Consider how multiple guards work together in NestJS.

Practice

(1/5)
1. What is the main purpose of a guard in NestJS when protecting routes?
easy
A. To decide if a request can access a route based on custom logic
B. To format the response data before sending it
C. To handle database connections automatically
D. To log every request made to the server

Solution

  1. Step 1: Understand the role of guards

    Guards in NestJS are designed to control access to routes by running custom logic before the route handler executes.
  2. Step 2: Identify the correct purpose

    Among the options, only deciding if a request can access a route matches the guard's role.
  3. Final Answer:

    To decide if a request can access a route based on custom logic -> Option A
  4. Quick Check:

    Guards control access = C [OK]
Hint: Guards allow or block access before route runs [OK]
Common Mistakes:
  • Confusing guards with interceptors or middleware
  • Thinking guards modify response data
  • Assuming guards handle database tasks
2. Which of the following is the correct way to apply a guard to a route in NestJS?
easy
A. @UseGuards(AuthGuard) before the controller class
B. @UseGuards(AuthGuard) before the route handler method
C. @ApplyGuard(AuthGuard) inside the constructor
D. @Guard(AuthGuard) before the route handler

Solution

  1. Step 1: Recall the decorator for guards

    The correct decorator to apply guards in NestJS is @UseGuards().
  2. Step 2: Identify correct placement

    This decorator can be placed before a route handler method or a controller class. @UseGuards(AuthGuard) before the route handler method correctly shows it before a route handler method.
  3. Final Answer:

    @UseGuards(AuthGuard) before the route handler method -> Option B
  4. Quick Check:

    @UseGuards + route method = D [OK]
Hint: Use @UseGuards() decorator on methods or controllers [OK]
Common Mistakes:
  • Using @Guard or @ApplyGuard which don't exist
  • Placing decorators inside constructor
  • Confusing middleware with guards
3. Given this guard implementation, what will happen when a request is made?
import { CanActivate, ExecutionContext } from '@nestjs/common';

export class AlwaysDenyGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    return false;
  }
}

Applied to a route, what is the result?

medium
A. The guard throws an error causing a server crash
B. The route handler runs and returns its response
C. The request is blocked and the route handler does not run
D. The guard logs the request but allows it

Solution

  1. Step 1: Analyze the canActivate method

    The guard's canActivate method always returns false, meaning it denies access.
  2. Step 2: Understand guard effect on route

    When canActivate returns false, NestJS blocks the request and does not run the route handler.
  3. Final Answer:

    The request is blocked and the route handler does not run -> Option C
  4. Quick Check:

    canActivate false blocks request = A [OK]
Hint: canActivate false means block access [OK]
Common Mistakes:
  • Thinking false lets the route run
  • Assuming guard throws error on false
  • Confusing logging with blocking
4. Identify the error in this guard code snippet:
import { CanActivate, ExecutionContext } from '@nestjs/common';

export class MyGuard implements CanActivate {
  canActivate(context: ExecutionContext) {
    if (context.switchToHttp().getRequest().user) {
      return true;
    }
  }
}
medium
A. Incorrect import of ExecutionContext
B. Using switchToHttp() is not allowed in guards
C. canActivate should be async but is not
D. Missing return statement when user is not present

Solution

  1. Step 1: Check canActivate return paths

    The method returns true if user exists, but returns nothing (undefined) otherwise.
  2. Step 2: Understand guard return requirements

    canActivate must always return a boolean or Promise<boolean>. Missing return means undefined, which is invalid.
  3. Final Answer:

    Missing return statement when user is not present -> Option D
  4. Quick Check:

    All paths must return boolean = B [OK]
Hint: Always return true or false in canActivate [OK]
Common Mistakes:
  • Forgetting else return false
  • Assuming undefined is false
  • Thinking async is always required
5. You want to protect a route so only users with role 'admin' can access it. Which guard implementation correctly enforces this?
import { CanActivate, ExecutionContext } from '@nestjs/common';

export class RolesGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    // Which condition correctly checks for admin role?
  }
}
hard
A. return user && user.role === 'admin';
B. return user && user.roles.includes('admin');
C. return user && user.roles === 'admin';
D. return user && user.role.includes('admin');

Solution

  1. Step 1: Understand user role structure

    Assuming user has a single role string in property role, not an array.
  2. Step 2: Check each condition

    return user && user.role === 'admin'; correctly compares user.role === 'admin'. return user && user.roles.includes('admin'); assumes roles is an array, which may be incorrect. Options C and D misuse property types.
  3. Final Answer:

    return user && user.role === 'admin'; -> Option A
  4. Quick Check:

    Check user.role string equals 'admin' = A [OK]
Hint: Match exact role property type to check admin [OK]
Common Mistakes:
  • Confusing roles array with single role string
  • Using includes on a string property
  • Checking wrong property name
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard