Graphql mutation 에러 해결

Seunghwa's Devlog·2022년 7월 28일
0

NestJs

목록 보기
2/15
post-thumbnail

NestJs와 graphql과 Cognito를 사용해 로그인 로직을 구현중에 mutation을 사용할 때 에러가 발생하였고 다음과 같이 해결하였다.

발생 에러 : "Cannot return null for non-nullable field LoginResponse.id_token."

  • dto/login-response.ts
import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class LoginResponse {
  @Field()
  id_token: string;
}
  • auth.resolver.ts
import { BadRequestException, UseGuards } from '@nestjs/common';
import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';
import { User } from 'src/users/entities/user.entity';
import { AuthService } from './auth.service';
import { CognitoAuthGuard } from './cognito.guard';
import { CurrentUser } from './currentUser.decorator';
import { LoginResponse } from './dto/login-response';
import { LoginUserInput } from './dto/login-user.input';
import { SignUpUserInput } from './dto/signup-user.input';
import { SignUpInfo } from './entities/signup.entity';

@Resolver()
export class AuthResolver {
  constructor(private authService: AuthService) {}


  @Mutation(() => LoginResponse)
  login(
    @Args('loginUserInput')
    loginUserInput: LoginUserInput,
    @Context() context,
  ) {
    try {
      return this.authService.login(loginUserInput);
    } catch (err) {
      throw new BadRequestException(err.message);
    }
  }

  @Mutation(() => SignUpInfo) 
  signup(@Args('signUpUserInput') signUpUserInput: SignUpUserInput) {
    return this.authService.signup(signUpUserInput);
  }
}

LoginResponse에서 id_token을 return 해줘야하는데, null로 return을 해서 발생하는 에러였다.

  • 해결방법 : LoginResponse가 @ObjectType으로 선언되었으므로 객체 타입인데, String 타입으로 받으려고 했기 때문이다.
    넘겨줄 때 객체로 변환해서 넘겨주었다.

  • auth.service.ts

import { JwtService } from '@nestjs/jwt';
import { UsersService } from './../users/users.service';
import { Inject, Injectable } from '@nestjs/common';
import { User } from 'src/users/entities/user.entity';
// import * as bcrypt from 'bcrypt';
import {
  AuthenticationDetails,
  CognitoUser,
  CognitoUserAttribute,
  CognitoUserPool,
} from 'amazon-cognito-identity-js';
import { AuthConfiguration } from './auth.configuration';
import { SignUpUserInput } from './dto/signup-user.input';
import { LoginUserInput } from './dto/login-user.input';

@Injectable()
export class AuthService {
  private userPool: CognitoUserPool;
  constructor(
    private readonly authConfig: AuthConfiguration,
    private usersService: UsersService,
    private jwtService: JwtService,
  ) {
    this.userPool = new CognitoUserPool({
      UserPoolId: this.authConfig.userPoolId,
      ClientId: this.authConfig.clientId,
    });
  }

  signup(registerRequest: SignUpUserInput) {
    return new Promise((resolve, reject) => {
      return this.userPool.signUp(
        registerRequest.username,
        registerRequest.password,
        [
          new CognitoUserAttribute({
            Name: 'email',
            Value: registerRequest.email,
          }),
        ],
        null,
        (err, result) => {
          if (!result) {
            console.log(err);
            reject(err);
          } else {
            resolve(result.user);
          }
        },
      );
    });
  }

  login(user: LoginUserInput) {
    const authenticationDetails = new AuthenticationDetails({
      Username: user.username,
      Password: user.password,
    });
    const userData = {
      Username: user.username,
      Pool: this.userPool,
    };
    const newUser = new CognitoUser(userData);

    return new Promise((resolve, reject) => {
      return newUser.authenticateUser(authenticationDetails, {
        onSuccess: (result) => {
        // 원래 코드 : resolve(result.getIdToken().getJwtToken());
          resolve({ id_token: result.getIdToken().getJwtToken() }); // 변경 후 코드 -> id_token을 객체로 변환하여 넘겨주었다.
        },
        onFailure: (err) => {
          reject(err);
        },
      });
    });
  }
}
profile
에러와 부딪히고 새로운 것을 배우며 성장해가는 과정을 기록합니다!

0개의 댓글