Documentation | NestJS - A progressive Node.js framework
$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
@nestjs/passport
와 passport
패키지는 설치해야함@nestjs/passport
가 nestjs
에서 passport
전략 사용할 수 있게 해줌@types
붙은 패키지는 TypeScript code 쓸 때 도와주는 패키지import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super();
}
async validate(username: string, password: string): Promise<any> {
const user = await this.authService.validateUser(username, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({
//유저이름을 이메일로 변경
usernameField: 'email',
});
}
async validate(email: string, password: string): Promise<any> {
const user = await this.authService.validateUser(email, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
$ nest g module auth
$ nest g service auth
import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
@Injectable()
export class AuthService {
constructor(private usersService: UsersService) {}
async validateUser(username: string, pass: string): Promise<any> {
const user = await this.usersService.findOne(username);
if (user && user.password === pass) {
const { password, ...result } = user;
return result;
}
return null;
}
}
import { Injectable } from '@nestjs/common';
import { UserService } from 'src/user/user.service';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';
@Injectable()
export class AuthService {
constructor(
private userService: UserService,
) {}
async validateUser(email: string, password: string): Promise<any> {
//email을 parameter로 받기 때문에 email로 user정보 가져온다.
const user = await this.userService.findOneByEmail(email);
// user의 password는 bcrypt로 암호화 되었기 때문에
// bcrypt의 compare 메소드로 클라이언드에서 보낸 password와 user의 password를 비교한다.
const validatePassword = await bcrypt.compare(password, user.password);
if (user && validatePassword) {
const { password, ...result } = user;
return result;
}
return null;
}
}
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
@Module({
imports: [UsersModule, PassportModule],
providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
Guard를 활용해 passport 전략을 실행한다.
→ 인증되지 않은 사용자의 접근을 차단한다.
Documentation | NestJS - A progressive Node.js framework
import { Controller, Request, Get, Post, UseGuards } from '@nestjs/common';
import { AppService } from './app.service';
import { AuthService } from './auth/auth.service';
import { LocalAuthGuard } from './auth/local-auth.guard';
@Controller()
export class AppController {
constructor(private authService: AuthService) {}
// AuthGuard('local')을 상속하는 LocalAuthGuard 클래스
@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
return req.user;
}
}