📖 Scenario: You are building a simple NestJS application that needs to protect certain routes from unauthorized access. Guards in NestJS help decide if a request can continue or not.
🎯 Goal: Build a basic guard that controls access to a route by checking a simple condition.
📋 What You'll Learn
Create a guard class implementing CanActivate
Add a boolean variable isAllowed to control access
Use the guard in a controller route
Return true or false from the guard based on isAllowed
💡 Why This Matters
🌍 Real World
Guards are used in real applications to protect routes from unauthorized users, like checking login status or permissions.
💼 Career
Understanding guards is essential for backend developers working with NestJS to build secure APIs.
Progress0 / 4 steps
1
Create the Guard Class
Create a class called SimpleGuard that implements CanActivate from @nestjs/common. Inside it, define a method canActivate(context: ExecutionContext): boolean that returns true.
NestJS
Hint
Remember to import CanActivate and ExecutionContext from @nestjs/common.
2
Add Access Control Variable
Inside the SimpleGuard class, add a boolean variable called isAllowed and set it to false. Change the canActivate method to return the value of this.isAllowed.
NestJS
Hint
Use this.isAllowed inside canActivate to control access.
3
Apply Guard to Controller Route
Create a controller class called AppController with a method getData() that returns the string 'Protected Data'. Use the @UseGuards(SimpleGuard) decorator on the getData method. Import necessary decorators from @nestjs/common.
NestJS
Hint
Use @Controller(), @Get('data'), and @UseGuards(SimpleGuard) decorators properly.
4
Enable Access by Changing Guard Variable
In the SimpleGuard class, change the isAllowed variable to true so the guard allows access to the route.
NestJS
Hint
Set isAllowed to true to allow access.
Practice
(1/5)
1. What is the main purpose of guards in a NestJS application?
easy
A. To format the response data before sending it to the client
B. To control access by allowing or blocking requests based on conditions
C. To manage database connections and queries
D. To handle errors and exceptions globally
Solution
Step 1: Understand the role of guards
Guards are designed to check conditions before a route handler runs, deciding if access should be granted.
Step 2: Compare with other responsibilities
Formatting responses, managing database, and error handling are done by other parts of NestJS, not guards.
Final Answer:
To control access by allowing or blocking requests based on conditions -> Option B
Quick Check:
Guards control access = A [OK]
Hint: Guards decide if a request can proceed or not [OK]
Common Mistakes:
Confusing guards with interceptors or filters
Thinking guards handle data formatting
Assuming guards manage database logic
2. Which of the following is the correct way to apply a guard to a controller method in NestJS?
easy
A. @UseGuards(AuthGuard) before the method declaration
B. @Guard(AuthGuard) inside the method body
C. UseGuards(AuthGuard) as a function call in the constructor
D. Apply guard logic directly inside the controller constructor
Solution
Step 1: Recall NestJS guard syntax
Guards are applied using the @UseGuards() decorator placed before the method or class.
Step 2: Evaluate options
Only @UseGuards(AuthGuard) before the method declaration uses the correct decorator syntax before the method. Others misuse syntax or placement.
Final Answer:
@UseGuards(AuthGuard) before the method declaration -> Option A
Quick Check:
@UseGuards decorator = A [OK]
Hint: Use @UseGuards decorator above methods or classes [OK]
Common Mistakes:
Using @Guard instead of @UseGuards
Calling UseGuards as a function inside constructor
Placing guard logic inside constructor instead of decorator
What will happen if a user without isAdmin tries to access the guarded route?
medium
A. Access will be granted because the guard always returns true
B. The guard will ignore the user and allow access
C. An error will be thrown due to missing isAdmin property
D. Access will be denied because isAdmin is false or missing
Solution
Step 1: Analyze the guard condition
The guard returns true only if request.user exists and request.user.isAdmin is truthy.
Step 2: Consider user without isAdmin
If isAdmin is false or missing, the condition returns false, denying access.
Final Answer:
Access will be denied because isAdmin is false or missing -> Option D
Quick Check:
Guard returns false if not admin = B [OK]
Hint: Guard returns true only if user is admin [OK]
Common Mistakes:
Assuming missing property causes error
Thinking guard always returns true
Ignoring the boolean check on isAdmin
4. Identify the error in this guard implementation:
canActivate(context: ExecutionContext) {
const request = context.getRequest();
if (!request.user) {
throw new Error('User not found');
}
return true;
}
medium
A. Throwing an error inside a guard instead of returning false
B. Missing async keyword for canActivate method
C. Using context.getRequest() instead of context.switchToHttp().getRequest()
D. Returning true without checking user roles
Solution
Step 1: Check method usage for request
While context.getRequest() is invalid, the main issue is guard behavior on failure.
Step 2: Understand guard error handling
Guards should return false to deny access, not throw errors which cause server crashes.
Final Answer:
Throwing an error inside a guard instead of returning false -> Option A
Quick Check:
Guards return false, not throw errors [OK]
Hint: Return false to block access, don't throw errors in guards [OK]
Common Mistakes:
Throwing errors instead of returning false
Using incorrect context method for request
Assuming async is required without async code
5. You want to restrict access to a route only to logged-in users with the role 'admin' or 'moderator'. Which guard logic correctly implements this?
hard
A. Return true if request.user does not exist
B. Return true if request.user exists and request.user.role === 'admin' && request.user.role === 'moderator'
C. Return true if request.user exists and request.user.role === 'admin' || request.user.role === 'moderator'
D. Return true if request.user exists and request.user.role !== 'admin' || request.user.role !== 'moderator'
Solution
Step 1: Understand role conditions
The user must be logged in and have role 'admin' OR 'moderator' to access.
Step 2: Evaluate logical operators
Return true if request.user exists and request.user.role === 'admin' || request.user.role === 'moderator' uses OR (||) correctly. Return true if request.user exists and request.user.role === 'admin' && request.user.role === 'moderator' uses AND (&&) which is impossible for one role. Return true if request.user exists and request.user.role !== 'admin' || request.user.role !== 'moderator' uses negations incorrectly. Return true if request.user does not exist allows access without user.
Final Answer:
Return true if request.user exists and request.user.role === 'admin' || request.user.role === 'moderator' -> Option C
Quick Check:
Use OR for multiple allowed roles = D [OK]
Hint: Use OR (||) to allow multiple roles [OK]
Common Mistakes:
Using AND (&&) instead of OR (||) for roles
Allowing access when user is missing
Incorrect negation logic in conditions
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.