@IsPublic 어노테이션으로 RefreshTokenGuard에서 RefreshToken 검증을 하기 위한 코드 공유
342
작성한 질문수 138
// is-public.const.ts
export enum IsPublicEnum {
ISPUBLIC = 'ISPUBLIC',
ISREFRESHTOKEN = 'ISREFRESHTOKEN',
}// is-public.decorator.ts
import { SetMetadata } from '@nestjs/common';
import { IsPublicEnum } from '../const/is-public.const';
export const ISPUBLIC_KEY = 'is_public';
export const IsPublic = (status: IsPublicEnum) =>
SetMetadata(ISPUBLIC_KEY, status);// bearer-token.guard.ts
@Injectable()
export class BearerTokenGuard implements CanActivate {
constructor(
private readonly authService: AuthService,
private readonly usersService: UsersService,
public readonly reflector: Reflector,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
const requiredPublic = this.reflector.getAllAndOverride(ISPUBLIC_KEY, [
context.getHandler(),
context.getClass,
]);
if (requiredPublic) {
req.requiredPublic = requiredPublic;
}
if (requiredPublic === IsPublicEnum.ISPUBLIC) {
return true;
}
const rawToken = req.headers['authorization'];
if (!rawToken) throw new UnauthorizedException('토큰이 없습니다!');
const token = this.authService.extractTokenFromHeader(rawToken, true);
const result = await this.authService.verifyToken(token);
const user = await this.usersService.getUserByEmail(result.email);
req.user = user;
req.token = token;
req.tokenType = result.type;
return true;
}
}추가된 코드
if (requiredPublic) {
req.requiredPublic = requiredPublic;
}requiredPublic 있을때만 req에 담아줌.
추가된 코드
if (requiredPublic === IsPublicEnum.ISPUBLIC) {
return true;
}IsPublic일때만 return true 즉, ISREFRESHTOKEN 일때는 아래 로직들이 정상적으로 실행됨.
// bearer-token.guard.ts
@Injectable()
export class AccessTokenGuard extends BearerTokenGuard {
async canActivate(context: ExecutionContext): Promise<boolean> {
await super.canActivate(context);
const req = context.switchToHttp().getRequest();
if (
req.requiredPublic === IsPublicEnum.ISPUBLIC ||
IsPublicEnum.ISREFRESHTOKEN
) {
return true;
}
if (req.tokenType !== 'access') {
throw new UnauthorizedException('Access Token이 아닙니다.');
}
return true;
}
}추가된 코드
if (req.requiredPublic === IsPublicEnum.ISPUBLIC || IsPublicEnum.ISREFRESHTOKEN) {
return true;
}req.requiredPublic이 ISPUBLIC이거나 ISREFRESHTOKEN이면 return true로 global accessTokenGuard return true로 빠져나옴.
// bearer-token-guard.ts
@Injectable()
export class RefreshTokenGuard extends BearerTokenGuard {
async canActivate(context: ExecutionContext): Promise<boolean> {
await super.canActivate(context);
const req = context.switchToHttp().getRequest();
if (req.tokenType !== 'refresh') {
throw new UnauthorizedException('Refresh Token이 아닙니다.');
}
return true;
}
}변경 사항 없음. 왜냐하면 위에서 정상적으로 refreshToken을 verify하고 req에 값이 담겼기 때문에 RefreshTokenGuard가 정상적으로 실행 되어야함.
auth.controller에 적용하기
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@IsPublic(IsPublicEnum.ISREFRESHTOKEN)
@Post('token/access')
@UseGuards(RefreshTokenGuard)
postTokenAccess(@Headers('authorization') rawToken: string) {
...
}
@IsPublic(IsPublicEnum.ISREFRESHTOKEN)
@Post('token/refresh')
@UseGuards(RefreshTokenGuard)
postTokenRefresh(@Headers('authorization') rawToken: string) {
...
}
@IsPublic(IsPublicEnum.ISPUBLIC)
@Post('login/email')
@UseGuards(BasicTokenGuard)
postLoginEmail(@Headers('authorization') rawToken: string) {
...
}
@IsPublic(IsPublicEnum.ISPUBLIC)
@Post('register/email')
postRegisterEmail(@Body() body: RegisterUserDto) {
...
}
}
답변 2
0
안녕하세요 혹시 AccessTokenGuard를 전역적으로 지정해준 상태에서
@isPublic , @UseGuards(RefreshTokenGuard) 어노테이션이 적용된 api가 리프레쉬가드를 못타는 문제 때문에 코드 수정하신거 맞으신가요?
cascade 질문
0
40
1
@types/bcrypt 설치과정이 누락된것같습니다.
0
49
1
process.env port key 에러
0
47
1
추상화
0
50
1
[공유] DTO optional 필드가 undefined로 잡혀 TypeORM 조건이 깨지는 현상
0
101
2
where 키워드가 들어가는 메서드와 아닌 메서드
0
57
1
BearerTokenGuard에서 db를 조회해서 유저 정보를 불러오는 이유?
0
72
1
app.controller app.service 는 지워도되나요?
0
70
1
@JoinColumn을 쓰는 경우와 안쓰는 경우의 차이
0
79
1
포트 3000에서 listen하는 곳까지 넘어가지 않습니다.
0
68
1
PickType 사용 시 `as const`를 꼭 사용해야 하나요?
0
102
2
socket connect 오류
0
98
2
강의를 들으면서 궁금한 점
0
97
2
DELETE 요청의 반환값은 어떤 기준으로 결정하는 게 좋을까요?
0
60
2
커리큘럼 질문
0
100
2
put 요청은 언제
0
90
3
typeorm VS prisma
0
351
2
142 강의 > 4:00 > 포스트멘 활용 관련 질문 드립니다.
0
78
2
User 데코레이터 버그 수정 전달드립니다.
0
67
1
git 주소 부탁드립니다.
0
113
2
nest g resource 명령어 에러
0
99
2
로그인 엔드포인트 관련 질문
0
85
2
yarn으로 express 다운 후 node 2_server.js 실행 안되는 경우
0
148
3
"흔히 사용되는 메서드" 강의 관련 질문입니다~
0
95
2





