jwt.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
// jwtGuard => jwtstrategy
흐름은 guard를 거쳐 strategy로 간다.
jwt.payload.ts
export type Payload = {
email: string;
sub: string;
};
jwt.strategy.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { Payload } from './jwt.payload';
import { CatsRepository } from 'src/cats/cats.repository';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly catsRepository: CatsRepository) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), // Header의 token에서 추출
secretOrKey: 'secret', // key, 유출되면 안됨, AuthModule의 JwtModule.register의 secret와 맞춰줘야한다.
igonoreExpiration: false, // 만료되는 기간
}); // jwt에 대한 설정
}
async validate(payload: Payload) {
const cat = await this.catsRepository.findCatByIdWithoutPassword(
payload.sub,
);
if (cat) {
return cat; // request.user
} else {
throw new UnauthorizedException('접근 오류');
}
}
}
nest.js에서 validate
함수는 @nestjs/passport
모듈과 Passport 라이브러리의 통합의 일부로 자동으로 실행된다.
validate
함수가 사용자 객체를 반환하면, Passport는 이 객체를 현재 요청의 user
속성에 할당한다. 이를 통해 이후의 모든 컨트롤러나 서비스에서 **request.user
**를 통해 인증된 사용자의 정보에 접근할 수 있다.
함수 findCatByIdWithoutPassword
를 repository
파일에 작성해보자
cats.repository.ts
import { HttpException, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './cats.schema';
import { Model } from 'mongoose';
import { CatRequestDto } from './dto/cats.request.dto';
@Injectable()
export class CatsRepository {
constructor(@InjectModel(Cat.name) private readonly catModel: Model<Cat>) {}
async existsByEmail(email: string) {
try {
const result = await this.catModel.exists({ email });
return result;
} catch {
throw new HttpException('db error', 400);
}
}
async create(cat: CatRequestDto) {
return await this.catModel.create(cat);
}
async findCatByEmail(email: string) {
const cat = await this.catModel.findOne({ email });
return cat;
}
async findCatByIdWithoutPassword(catId: string) {
const cat = await this.catModel.findById(catId).select('-password'); // select로 password를 제외(-,마이너스)하고 가져온다. 보안상 이유로 가져오지 않는다.
return cat;
}
}
findById
로 catId
에 해당하는 유저를 찾고 select
로 해당 유저를 가져온다. 여기서는 select('-password')
를 사용해서 password를 제외(-,마이너스)하고 가져오는데 password는 보안상 이유로 가져오지 않는다.