😗 Guard
Guard 가 하는 기능은 단 한가지 입니다.
사용자의 요청에 따른 권한처리, 요청에 대한 승인처리를 진행합니다.
http://localhost:3000/guard 로 호출했을때, Guard 설정 시,
Controller가 호출 되기 전에 요청한 사용자의 권한등을 확인후,
승인된 사용자가 아닐경우 호출을 방지합니다.
호출 순서
: Middleware -> Guard -> pipe
Guard는 Middleware 다음에 호출 되며, Pipe는 Guard가 호출된 이후에 호출 됩니다.
테스트 방법
아래의 API 를 생성후, token을 생성해서 호출한다
http://localhost:3000/guard
headers Authorization Bearer {token}
token 생성
GuardController
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuards } from './auth.guard';
import { Roles } from './role.decorator';
@Controller("/guard")
export class GuardController {
@Get()
@UseGuards(AuthGuards)
@Roles(['admin'])
findOne() {
return "guard";
}
}
@Roles
해당 데코레이터는 어노테이션아닌가,, 무튼 해당 데코레이터는 nestJS에서 지원하는 내장 함수가아닌, 사용자 정의 데코레이터 입니다.
Reflector를 사용하면 사용자 데코레이터를 생성이 가능해집니다.
roles.Decorator.ts
import { Reflector } from "@nestjs/core";
export const Roles = Reflector.createDecorator<String[]>();
@UserGuards(AuthGuards)
userGuards 데코레이터 명시하면, (GET) /guard을 호출시, Guard 를 호출하게 된다.
auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
import { Observable } from 'rxjs';
import { Reflector } from "@nestjs/core";
import { Roles } from "./role.decorator";
@Injectable()
export class AuthGuards implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(
context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> {
const roles = this.reflector.get(Roles, context.getHandler());
if(!roles) {
return true;
}
const { user } = context.switchToHttp().getRequest();
if(roles[0] === user) {
return true;
}
return false;
}
}
const { user } = context.switchToHttp().getReuqest();
사용자가 요청한 reuqest.user에 값을 담기 위해서는 middleware에 JWT Token을 복호화해서
request에 복호화한 데이터를 저장해줘야한다.
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from 'express';
import * as jwt from 'jsonwebtoken';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const token = req.header('Authorization')?.replace('Bearer ', '');
console.log('token: ', token);
if (!token) {
return next();
}
try {
const decoded = jwt.verify(token, 'coderdev');
// const decoded = jwt.verify(token);
console.log(decoded);
req.user = decoded.user;
// req['user'] = decoded;
next();
} catch (error) {
return res.status(401).json({ message: '[Middleware] fail..' });
}
}
}
자세한 내용은 아래의 NestJS Doc Guards 참고.
https://docs.nestjs.com/guards
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
'NestJS' 카테고리의 다른 글
[NestJS] custom-decorators (0) | 2023.09.09 |
---|---|
[NestJS] Interceptors (0) | 2023.09.09 |
[NestJS] Pipes (0) | 2023.09.06 |
[NestJS] exception-filters (0) | 2023.09.05 |
[NestJS] Middleware (0) | 2023.09.05 |