본문 바로가기
NestJS

[NestJS] Guards

by NJ94 2023. 9. 8.

https://docs.nestjs.com/guards

 

 

😗 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 생성

https://jwt.io/

 

 

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