The local strategy helps check if a user's username and password are correct. It lets your app know who is trying to log in.
Local strategy (username/password) in NestJS
import { Strategy } from 'passport-local'; import { PassportStrategy } from '@nestjs/passport'; import { Injectable, UnauthorizedException } from '@nestjs/common'; @Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private authService: AuthService) { super(); // uses default fields: username and password } async validate(username: string, password: string): Promise<any> { const user = await this.authService.validateUser(username, password); if (!user) { throw new UnauthorizedException(); } return user; } }
The validate method checks the username and password.
Throwing UnauthorizedException stops login if credentials are wrong.
super({ usernameField: 'email' }); // This changes the field from 'username' to 'email' if your login uses email instead.
async validate(username: string, password: string) { const user = await this.authService.validateUser(username, password); if (!user) { throw new UnauthorizedException('Invalid credentials'); } return user; }
This example shows a simple AuthService with two users. The LocalStrategy uses it to check username and password. The testLogin function simulates two login attempts: one correct and one wrong.
import { Injectable, UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-local'; @Injectable() export class AuthService { private users = [ { id: 1, username: 'alice', password: 'wonderland' }, { id: 2, username: 'bob', password: 'builder' }, ]; async validateUser(username: string, password: string) { const user = this.users.find(u => u.username === username && u.password === password); if (user) { const { password, ...result } = user; return result; } return null; } } @Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private authService: AuthService) { super(); } async validate(username: string, password: string) { const user = await this.authService.validateUser(username, password); if (!user) { throw new UnauthorizedException(); } return user; } } // Example usage simulation async function testLogin() { const authService = new AuthService(); const strategy = new LocalStrategy(authService); try { const user = await strategy.validate('alice', 'wonderland'); console.log('Login success:', user); } catch (e) { console.log('Login failed'); } try { const user = await strategy.validate('alice', 'wrongpass'); console.log('Login success:', user); } catch (e) { console.log('Login failed'); } } testLogin();
Local strategy works with Passport.js inside NestJS.
Always keep passwords safe and hashed in real apps (this example uses plain text for simplicity).
Throwing UnauthorizedException stops the login process if credentials are wrong.
Local strategy checks username and password to log users in.
Use validate method to verify credentials.
Throw an error if login fails to stop access.
Practice
LocalStrategy in NestJS authentication?Solution
Step 1: Understand the role of LocalStrategy
The LocalStrategy is designed to check user credentials, specifically username and password, during login.Step 2: Differentiate from other strategies
Unlike JWT or OAuth strategies, LocalStrategy focuses on validating credentials, not token generation or registration.Final Answer:
To verify username and password for user login -> Option DQuick Check:
LocalStrategy = username/password check [OK]
- Confusing LocalStrategy with JWT token generation
- Thinking LocalStrategy handles user registration
- Assuming LocalStrategy encrypts passwords
Solution
Step 1: Recall LocalStrategy method names
In NestJS, the LocalStrategy requires avalidatemethod to check username and password.Step 2: Confirm method purpose
Thevalidatemethod returns the user if credentials are correct or throws an error if not.Final Answer:
validate() -> Option BQuick Check:
Credential check method = validate() [OK]
- Using authenticate() which is not a LocalStrategy method
- Confusing login() with validate()
- Assuming verify() is required
async validate(username: string, password: string) {
const user = await this.authService.validateUser(username, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}Solution
Step 1: Analyze the validate method logic
IfvalidateUserreturns no user (password incorrect), the code throwsUnauthorizedException.Step 2: Understand exception effect
ThrowingUnauthorizedExceptionstops the login process and signals failure.Final Answer:
An UnauthorizedException is thrown stopping login -> Option CQuick Check:
Wrong password = UnauthorizedException thrown [OK]
- Assuming user is returned even if password is wrong
- Thinking function returns null without error
- Believing password resets automatically
async validate(username: string, password: string) {
const user = this.authService.validateUser(username, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}Solution
Step 1: Check async call usage
The method callsvalidateUserwhich returns a Promise, but lacksawait.Step 2: Understand consequences of missing await
Withoutawait,useris a Promise, soif (!user)check is incorrect and login logic breaks.Final Answer:
Missing await before authService.validateUser call -> Option AQuick Check:
Async calls need await to get results [OK]
- Forgetting await on async service calls
- Throwing exceptions incorrectly
- Misordering parameters
validate method?Solution
Step 1: Understand the goal
Allow login by username or email using one validate method.Step 2: Best approach
ModifyvalidateUserto accept one identifier and check if it matches username or email, then verify password.Step 3: Why other options fail
Adding multiple validate methods or strategies complicates logic; changing password parameter is incorrect.Final Answer:
Modify validateUser to accept a single identifier and check both username and email -> Option AQuick Check:
One validate method, flexible identifier [OK]
- Creating multiple validate methods unnecessarily
- Using separate strategies for username and email
- Confusing password parameter with identifier
Ready to prove it?
Pass the test and this pattern moves unknown
