우선 토큰 인증에대한 기본지식을 익힌 후 팀원이 구현해놓은 데코레이터를 통해 어떤방식으로 진행되는지 파악했다. ****
이 부분에서 @UseGuard(JwtAuthGuard) / UseGuard 데코레이터를 통해 무엇인가 일어나고 이후 @GetUser() 데코레이터를 통해 userNo를 받게 되는것 같았다.
하나씩 파고 들어가보겠다.
Guard는 특정 상황들에 따라서 주어진 요청이 route handler에 의해 handling이 될지 말지 결정해준다.
요청은 midleware - guards - interceptors - pipes - controller 순으로 진행된다.
인증같은 로직을 수행할때 guard를 쓰면 cntroller에 가기 전 유저권한을 확인하여 요청을 더욱 효율적으로 관리할 수 있다.
JwtAuthGuard클래스 전체 코드이다. 아무것도 없다. 너무 아무것도 없어서 당황했었다.
아직 실력이 많이 부족해 자세한 설명은 힘들지만 AuthGuard의 인자인 jwt를 통해 인증 전략을 정하면 이에 맞는 로직이 흘러가는것 같다
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt } from 'passport-jwt';
import { Strategy } from 'passport-jwt';
import { Payload } from '../interface/auth.interface';
import { AuthService } from '../auth.service';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(
private readonly configService: ConfigService,
private readonly authService: AuthService,
) {
super({
ignoreExpiration: true,
secretOrKey: configService.get('JWT_SECRET_KEY'),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
});
}
async validate(tokenPayload: Payload) {
const { userNo } = tokenPayload;
const isTokenAvailable: boolean = await this.authService.validateToken(
tokenPayload,
);
if (!isTokenAvailable) {
const accessToken: string = await this.authService.refreshAccessToken({
userNo,
nickname: tokenPayload.nickname,
profileImage: tokenPayload.profileImage,
});
throw new UnauthorizedException({
message: '토큰이 만료되었습니다.',
accessToken,
});
}
return userNo;
}
}
AuthGuard의 인자로 전달받은 jwt라는 이름의 startegy 전체 코드이다.
인증전략은 JwtStrategy의 ‘jwt’부분을 통해 AuthGuard가 JwtStrategy클래스를 인증전략으로 사용가능하게 해준다.