AuthGuard, AuthUser Decoraotr

김종민·2022년 6월 28일
0

Nuber-Server

목록 보기
12/34

들어가기
resolver(Query, mutation)을 실행시키기 전에
Guard를 셋팅하면, resolver실행 전에,
Authorization을 확인가능하다.

https://docs.nestjs.com/guards

authentication: 토큰의 유효성 확인
authorization: 유저가 어떤일을 하기 전에 할 수 있는 권한이 있는지를 확인.

$nest g mo muth

1. AuthGuard

1. src/auth/auth.guard.ts

AuthGuard

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable() ///class type은 Injectable()으로한다.
export class AuthGuard implements CanActivate {
///CanActivate는 이후로 할수 있게 할건지, 할수 없게 할건지를 
///만들어 주는것, 아래 canActivate도 마찬가지

  canActivate(context: ExecutionContext) {
    const gqlContext = GqlExecutionContext.create(context).getContext();
    ///http에 담겨진 context를 grapqhQL context로 옮겨주는 과정
    
    const user = gqlContext['user'];
    ///grapqhQL context에서 user를 뽑아주고, 아래에서
    ///user가 있으면, 이후로 할 수 있게, 없으면, 이후의 것을 할 수 없게함.
    
    if (!user) {
      return false;
    }
    return true;
  }
}

2. AuthGuard 사용(users.resolver.ts)

  @UseGuards(AuthGuard)  ///맨위에 @UseGuards(사용할 가드) 끝. 사용은 무지 쉬움,
  @Query(() => UserProfileOutput)
  async userProfile(
    @Args() userProfileInput: UserProfileInput,
  ): Promise<UserProfileOutput> {
    try {
      const user = await this.usersService.findById(userProfileInput.userId);
      if (!user) {
        throw Error();
      }
      return {
        ok: true,
        user,
      };
    } catch (e) {
      return {
        error: 'User not found',
        ok: false,
      };
    }

2. AuthUser Decorator

apollo에서 처럼 loggedInUSer를 확인해 주고 return해 줌.

1. src/auth/auth-user.decorator.ts


import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

export const AuthUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
  ///위에 형식은 그대로 따라갈 것!
  
    const gqlContext = GqlExecutionContext.create(context).getContext();
    ///AuthGuard와 거의 비슷, http req의 context를 grapqhql context로 만들어줌.
    
    const user = gqlContext['user'];
    return user;  ///마지막에 graphql context에 담긴 user를 return해줌.
  },
);

2. 사용(users.resolver.ts)

  @UseGuards(AuthGuard)  ///context에 user가 있는지 확인하고 다음으로 보내줌!!
  @Mutation(() => EditProfileOutput)
  async editProfile(
    @AuthUser() authUser: User,
    @Args('input') editProfileInput: EditProfileInput,
  ): Promise<EditProfileOutput> {
  ///auth-user.decorator.ts에서 만든 AuthUser를 불러줌(@AuthUser)로~
  ///이 과정을 통해서, loggedInUset를 확인 가능함. 그래서 editProfile 가능하게
  
    try {
      await this.usersService.editProfile(authUser.id, editProfileInput);
      return {
        ok: true,
      };
    } catch (error) {
      return {
        ok: false,
        error,
      };
    }
  }
  1. AuthGuard와 AuthUser Decorator를 통해서, loggedInUser들만,
    이어서 나오는 resolver들이 실행가능해지게 쉴드를 쳐 놓음.

  2. resolver는 graphql이기 떄문에 context를 graphql context로 옮겨주는부분
    확실히 인지할것!!

  3. http, header에 있는 middleware 과정을 통해 token을 verify해서
    user를 찾아주는 과정을 함. 찾은 user를 graphql의 context에 담아 주어야
    모든 resolver에 적용시킬 수 있음.

profile
코딩하는초딩쌤

0개의 댓글