Bird
Raised Fist0
NestJSframework~5 mins

Local strategy (username/password) in NestJS

Choose your learning style10 modes available
Introduction

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.

When you want users to log in with a username and password.
When you need to protect parts of your app so only logged-in users can access them.
When you want to check user credentials before giving access.
When you want to handle login logic inside your NestJS app.
When you want to use Passport.js with NestJS for simple username/password login.
Syntax
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.

Examples
Use this if users log in with email instead of username.
NestJS
super({ usernameField: 'email' });

// This changes the field from 'username' to 'email' if your login uses email instead.
You can add a message to the exception to explain why login failed.
NestJS
async validate(username: string, password: string) {
  const user = await this.authService.validateUser(username, password);
  if (!user) {
    throw new UnauthorizedException('Invalid credentials');
  }
  return user;
}
Sample Program

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.

NestJS
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();
OutputSuccess
Important Notes

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.

Summary

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

(1/5)
1. What is the main purpose of the LocalStrategy in NestJS authentication?
easy
A. To encrypt user passwords
B. To generate JWT tokens for users
C. To handle user registration
D. To verify username and password for user login

Solution

  1. Step 1: Understand the role of LocalStrategy

    The LocalStrategy is designed to check user credentials, specifically username and password, during login.
  2. Step 2: Differentiate from other strategies

    Unlike JWT or OAuth strategies, LocalStrategy focuses on validating credentials, not token generation or registration.
  3. Final Answer:

    To verify username and password for user login -> Option D
  4. Quick Check:

    LocalStrategy = username/password check [OK]
Hint: Local strategy always checks username and password [OK]
Common Mistakes:
  • Confusing LocalStrategy with JWT token generation
  • Thinking LocalStrategy handles user registration
  • Assuming LocalStrategy encrypts passwords
2. Which method must be implemented in a NestJS LocalStrategy class to check user credentials?
easy
A. authenticate()
B. validate()
C. login()
D. verify()

Solution

  1. Step 1: Recall LocalStrategy method names

    In NestJS, the LocalStrategy requires a validate method to check username and password.
  2. Step 2: Confirm method purpose

    The validate method returns the user if credentials are correct or throws an error if not.
  3. Final Answer:

    validate() -> Option B
  4. Quick Check:

    Credential check method = validate() [OK]
Hint: LocalStrategy uses validate() to check credentials [OK]
Common Mistakes:
  • Using authenticate() which is not a LocalStrategy method
  • Confusing login() with validate()
  • Assuming verify() is required
3. Given this LocalStrategy snippet, what happens if the password is incorrect?
async validate(username: string, password: string) {
  const user = await this.authService.validateUser(username, password);
  if (!user) {
    throw new UnauthorizedException();
  }
  return user;
}
medium
A. The function returns null silently
B. The user object is returned anyway
C. An UnauthorizedException is thrown stopping login
D. The password is reset automatically

Solution

  1. Step 1: Analyze the validate method logic

    If validateUser returns no user (password incorrect), the code throws UnauthorizedException.
  2. Step 2: Understand exception effect

    Throwing UnauthorizedException stops the login process and signals failure.
  3. Final Answer:

    An UnauthorizedException is thrown stopping login -> Option C
  4. Quick Check:

    Wrong password = UnauthorizedException thrown [OK]
Hint: Throw UnauthorizedException if user not found [OK]
Common Mistakes:
  • Assuming user is returned even if password is wrong
  • Thinking function returns null without error
  • Believing password resets automatically
4. Identify the error in this LocalStrategy validate method:
async validate(username: string, password: string) {
  const user = this.authService.validateUser(username, password);
  if (!user) {
    throw new UnauthorizedException();
  }
  return user;
}
medium
A. Missing await before authService.validateUser call
B. UnauthorizedException should not be thrown
C. validate method should not be async
D. username and password parameters are reversed

Solution

  1. Step 1: Check async call usage

    The method calls validateUser which returns a Promise, but lacks await.
  2. Step 2: Understand consequences of missing await

    Without await, user is a Promise, so if (!user) check is incorrect and login logic breaks.
  3. Final Answer:

    Missing await before authService.validateUser call -> Option A
  4. Quick Check:

    Async calls need await to get results [OK]
Hint: Always await async calls in validate() [OK]
Common Mistakes:
  • Forgetting await on async service calls
  • Throwing exceptions incorrectly
  • Misordering parameters
5. You want to customize the LocalStrategy to allow login with either username or email. Which change is best to implement in the validate method?
hard
A. Modify validateUser to accept a single identifier and check both username and email
B. Add a second validate method for email login
C. Use two separate LocalStrategy classes for username and email
D. Change the password parameter to accept email instead

Solution

  1. Step 1: Understand the goal

    Allow login by username or email using one validate method.
  2. Step 2: Best approach

    Modify validateUser to accept one identifier and check if it matches username or email, then verify password.
  3. Step 3: Why other options fail

    Adding multiple validate methods or strategies complicates logic; changing password parameter is incorrect.
  4. Final Answer:

    Modify validateUser to accept a single identifier and check both username and email -> Option A
  5. Quick Check:

    One validate method, flexible identifier [OK]
Hint: Use one validate method checking username or email [OK]
Common Mistakes:
  • Creating multiple validate methods unnecessarily
  • Using separate strategies for username and email
  • Confusing password parameter with identifier
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