ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NestJS 기본강의 - 4. 인증
    NestJS/NestJS 기본강의 2022. 7. 8. 18:32

    CLI를 이용한 모듈, 컨트롤러, 서비스 생성

    - nest g module auth

        ㆍauth 모듈 생성

    - nest g controller auth --no-spec

        ㆍauth 컨트롤러 생성

    - nest g service auth --no-spec

        ㆍauth 서비스 생성

     


    - 비밀번호 암호화

    bcryptjs

    npm install bcryptjs --save
    import * as bcrypt from 'bcryptjs';

     

    비밀번호를 데이터베이스에 저장하는 방법

    1. 원본 비밀번호를 저장 (최악)

     

    2. 비밀번호를 암호화 키 ( Encryption Key )와 함께 암호화 ( 양방향 )

    - 어떠한 암호를 이용해서 비밀번호를 암호화하고 그 암호를 이용하여 복호화도 가능

    - 암호화 키가 노출되면 알고리즘은 대부분 오픈되어있기 떄문에 위험도가 높음

     

    3. SHA256등 Hash로 암호화해서 저장 ( 단방향 )

    - 암호화만 존재, 복호화가 없음

    - 레인보우 테이블을 만들어서 암호화된 비밀번호를 비교해서 비밀번호를 알아냄

     

    4. 솔트(salt) + 비밀번호(Plain Password)를 해시Hash로 암호화해서 저장

    - 암호화할 때 원래 비밀번호에다 salt를 붙인 후에 해시로 암호화를 한다.

    import * as bcrypt from 'bcryptjs';
    
        const salt = await bcrypt.getSalt();
        const hashedPassword = await bcrypt.hash(password, salt);
        const user = this.create({ username, password: hashedPassword });

    JWT

    - JWT( JSON Web Token )는 당사자간에 정보를 JSON 개체로 안전하게 전송하기위한 컴팩트하고 독립적인 방식을 정의하는 개방형 표준(RFC 7519)이다. 이 정보는 디지털 서명이되어 있으므로 확인하고 신뢰할 수 있다

    - 간단히 애기하자면 정보를 안전하게 전할 때 혹은 유저의 권한 같은 것을 체크를 하기 위해서 사용하는데 유용한 모듈

     

    JWT의 구조

    - Header : 토큰에 대한 메타 데이터를 포함하고 있다

                     ( 타입, 해싱 알고리즘 SHA256, RSA ... )

    - Payload : 유저 정보(issuer), 만료 기간(expiration time), 주제(subject) 등등...

    - Verify Signature : JWT의 마지막 세그먼트는 토큰이 보낸 사람에 의해 서명되었으며 어떤 식으로든 변경되지 않았는지 확인하는데 사용되는 서명이다.

    서명은 헤더 및 페이로드 세그먼트, 서명 알고리즘, 비밀 또는 공개 키를 사용하여 생성

     

    * 클라이언트에서 온 Headers + 클라이언트에서 온 Payload + 서버에서 가지고 있는 Secret Text 와

    클라이언트에서온 Verify Signature을 비교

     

     

    - JWT 모듈 + Passport모듈 ( JWT를 이용해서 인증 처리하는 등의 과정을 쉽게 만듬 )

    필요한 모듈 설치

    - @nestjs/jwt

        ㆍnestjs에서 jwt를 사용하기 위해 필요한 모듈

    - @nestjs/passport

        ㆍnestjs에서 passport를 사용하기 위해 필요한 모듈

    - passport

        ㆍpassport 모듈

    - passport-jwt

        ㆍjwt모듈

    npm install @nestjs/jwt @nestjs/passport passport passport-jwt --save

     

    @Module({
      imports: [
        JwtModule.register({
            secret: 'Secret1234'
            signOptions: {
                expiresIn : 60*60,
            }
        }),
    })

    - Secret : 토큰을 만들 때 이용한 Secret 텍스트

    - ExpiresIn : 정해진 시간 이후에는 토큰이 유효하지 않게 됩니다. 60 * 60은 한 시간 이후에는 이 토큰이 더 이상 유효하지 않게 된다.

     

    Passport

    - @types/passport-jwt 모듈 ( passport-jwt 모듈을 위한 타입 정의 모듈 )

    npm install @types/passport-jwt --save

    NestJS에서 Middleware들에 대해서

    NestJS에는 여러가지 미들웨어가 있다

    - Pipes, Filters, Guards, Interceptors 등의 미들웨어로 취급되는 것들이 있는데 각각 다른 모적을 가지며 사용되고 있다.

     

    Pipes

    - 파이프는 요청 유효성 검사 및 페이로드 변환을 위해 만들어진다.

    - 데이터를 예상한 대로 직렬화한다.

     

    Filters

    - 필터는 오류 처리 미들웨어이다

    - 특정 오류 처리기를 사용할 경로와 각 경로 주변의 복잡성을 관리하는 방법을 알 수 있다

     

    Guards

    - 가드는 인증 미들웨어이다

    - 지정된 경로로 통과할 수 있는 사람과 허용되지 않는 사람을 서버에 알려준다

     

    Interceptors

    - 인터셉터는 응답 매핑 및 캐시 관리와 함께 요청 로깅과 같은 전후 미들웨어이다

    - 각 요청 전후에 이를 실행하는 기능은 매우 강력하고 유용하다

     

    가각의 미들웨어가 불러지는(called) 순서

    middleware → guard → intercerptor(before) → pipe → contoller → service

                       → controller → interceptor(after) → filter ( if applicable ) → client

     

     


    UseGuards

    - UseGuards 안에 @nestjs/passport에서 가져온 AuthGuard() 를 이용하면 요청안에 유저 정보를 넣어줄 수 있다

      ( req안에 jwt.strategy.ts 파일의 validate의 return값인 user 을 넣어줄 수 있다 )

    @Post('/authTest')
    @UseGuards(AuthGuard())
    authTest(@Req() req) {
        console.log(req);
    ]

     

    * 뭔가 spring security 처럼 UseGuards가 PassportStrategy를 찾아가는 거 같음...?

     


    req.user가 아닌 바로 user라는 파라미터를 가져올 수 있는 방법은??

    - 커스텀 데코레이터

    import { createParamDecorator, ExecutionContext } from '@nestjs/common';
    import { User } from './user.entity';
    
    export const GetUser = createParamDecorator(
      (data, ctx: ExecutionContext): User => {
        const req = ctx.switchToHttp().getRequest();
        return req.user;
      },
    );

    - 사용 방법

      @Post('/test')
      @UseGuards(AuthGuard())
      test(@GetUser() user: User) {
        console.log('user', user);
      }

     

    댓글

Designed by Tistory.