Carpool(React Native & Express & apollo federation & Mariadb, Mongodb) - 5. gateway, auth-service(2)

yellow_note·2021년 12월 10일
0

#1 apollo gateway

다음의 명령어로 디렉토리를 생성하고 gateway를 위한 라이브러리를 설치하도록 하겠습니다.

mkdir api-gateway
cd api-gateway
npm init
mkdir src && touch src/index.js
npm install @apollo/gateway apollo-server-core apollo-server-express cors dotenv express graphql@15.8.0 nodemon winston winston-daily-rotate-file tsc-watch
npm install -D @types/express typescript

우선은 gateway 서버를 작동하기 위한 라이브러리만 설치하고 추후에 인증과 인가에 관한 기능을 작성할 때 관련 라이브러리를 설치하도록 하겠습니다.

  • api-gateway/.env
PORT=6900

AUTH_SERVICE_ENDPOINT=http://localhost:6000/auth-service
  • ./src/index.ts
require('dotenv').config();

import { ApolloServer } from 'apollo-server-express';
import { ApolloGateway } from '@apollo/gateway';
import { ApolloServerPluginDrainHttpServer } from 'apollo-server-core';
import express from 'express';
import cors from 'cors';
import http from 'http';
import { Authentication } from './auth/authentication';

const { 
    PORT,
    AUTH_SERVICE_ENDPOINT
} = process.env;

class Server {
    constructor() {}

    public async start() {
        const app = express();
        const httpServer = http.createServer(app);
        const server = new ApolloServer({
            gateway: new ApolloGateway({
                serviceList: [
                    {
                        name: "auth-service",
                        url: AUTH_SERVICE_ENDPOINT   
                    }
                ],
                buildService: ({
                    name,
                    url
                }) => {
                    return new Authentication({ url });
                }
            }),
            context: ({ req }) => {
                const token = req.headers.authorization;
    
                if(token) {
                    return { token };
                } 
            },
            plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
        });
    
        app.use(cors());
    
        await server.start();
    
        server.applyMiddleware({
            app,
            path: "/",
            cors: false
        });
    
        httpServer.listen({ port: PORT });
    
        console.log(`🚀 Server ready at http://localhost:${PORT}${server.graphqlPath}`);
    }
}

const server = async () => await new Server().start();

server();

apollo gateway에서는 serviceList에 subgraph 서버를 등록하여 하나의 gateway를 이용하여 등록된 서비스에 쿼리를 전송할 수 있는 마이크로 서비스의 구조를 사용할 수 있습니다.

이 정도로 gateway 서버를 작성해보았고 테스트를 진행해보도록 하겠습니다.

#2 auth-service test

서비스 인스턴스를 띄우고 난 다음에 gateway인스턴스를 띄우도록 하겠습니다.

메서드 별로 테스트를 진행해보도록 하겠습니다.

1) 회원가입

  • 운전자 데이터 등록

  • 승객 데이터 등록

  • variables의 nickname 밑에 "license": null이 있어야 하는데 실수로 지우고 캡쳐를 했습니다.

승객 데이터

{
  "_id": {
    "$oid": "61ba98b827fb701a2b026e5c"
  },
  "email": "test-email-001@example.com",
  "password": "$2b$10$J6gbgaAwk5jOVFXLvkD8L.JfiaebF97EB2yEskW.ayvSFMd3UHiO2",
  "nickname": "test-nickname-001",
  "created_at": "2021-12-16T01:39:04.632Z",
  "role": "PASSENGER",
  "license": null,
  "user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
  "is_delete": false,
  "__v": 0
}

운전자 데이터

{
  "_id": {
    "$oid": "61ba988827fb701a2b026e59"
  },
  "email": "test-email-002@example.com",
  "password": "$2b$10$Cp2/yVVJ7vzKuZRivz2axeUBY/LagwcTgDmP1RJU5dbPrnJQo.pYi",
  "nickname": "test-nickname-002",
  "created_at": "2021-12-16T01:38:16.979Z",
  "role": "DRIVER",
  "license": {
    "birth_date": "1990-01-01",
    "name": "test-name",
    "lic_number": "00-10288100",
    "_id": {
      "$oid": "61ba988827fb701a2b026e5a"
    }
  },
  "user_id": "cd9f524e-2609-4acc-95f6-abde4df6b479",
  "is_delete": false,
  "__v": 0
}

회원가입이 잘 진행된 모습을 볼 수 있습니다.

2) 로그인

  • 정상 로그인

토큰을 잘 반환합니다.

  • 잘못된 이메일

User not found 에러 메시지를 잘 반환합니다.

  • 잘못된 비밀번호

Wrong password 에러 메시지를 잘 반환합니다.

3) 유저 불러오기

유저의 정보를 잘 불러오는 모습을 볼 수 있습니다.

4) 닉네임 체크

  • 닉네임 중복

닉네임 중복 코드를 반환합니다.

  • 고유 닉네임

고유 닉네임임을 알리는 코드를 반환합니다.

5) 이메일 체크

  • 이메일 중복

이메일 중복 코드를 반환합니다.

  • 고유 이메일

고유 이메일임을 알리는 코드를 반환합니다.

6) 회원 정보 수정

  • 운전면허등록

  • 비밀번호 수정

  • 닉네임 수정

수정 전 데이터와 수정 후 데이터를 비교해보겠습니다.

  • 수정 전
{
  "_id": {
    "$oid": "61ba98b827fb701a2b026e5c"
  },
  "email": "test-email-001@example.com",
  "password": "$2b$10$J6gbgaAwk5jOVFXLvkD8L.JfiaebF97EB2yEskW.ayvSFMd3UHiO2",
  "nickname": "test-nickname-001",
  "created_at": "2021-12-16T01:39:04.632Z",
  "role": "PASSENGER",
  "license": null,
  "user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
  "is_delete": false,
  "__v": 0
}
  • 수정 후
{
  "_id": {
    "$oid": "61ba98b827fb701a2b026e5c"
  },
  "email": "test-email-001@example.com",
  "password": "$2b$10$mXi4lk6gSrVICX1Ie4U4j.z/B0iWM2TmvdAyP/U8y5kAW6enMB/W.",
  "nickname": "modify-nickname-001",
  "created_at": "2021-12-16T01:39:04.632Z",
  "role": "DRIVER",
  "license": {
    "birth_date": "1991-01-02",
    "name": "test-user-001",
    "lic_number": "02-11263671",
    "_id": {
      "$oid": "61baa7cf87bad08c82f58c99"
    }
  },
  "user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
  "is_delete": false,
  "__v": 0
}

비밀번호, 닉네임, 운전면허의 데이터가 잘 수정된 모습을 볼 수 있습니다.

7) 유저 삭제

{
  "_id": {
    "$oid": "61ba98b827fb701a2b026e5c"
  },
  "email": "test-email-001@example.com",
  "password": "$2b$10$mXi4lk6gSrVICX1Ie4U4j.z/B0iWM2TmvdAyP/U8y5kAW6enMB/W.",
  "nickname": "modify-nickname-001",
  "created_at": "2021-12-16T01:39:04.632Z",
  "role": "DRIVER",
  "license": {
    "birth_date": "1991-01-02",
    "name": "test-user-001",
    "lic_number": "02-11263671",
    "_id": {
      "$oid": "61baa7cf87bad08c82f58c99"
    }
  },
  "user_id": "7ef55bf7-8fdc-4ce4-bd8e-7e8508b3b310",
  "is_delete": true,
  "__v": 0
}

is_delete: true로 잘 변경되었습니다.

auth-service의 모든 메서드에 대한 테스트를 잘 진행해보았고, 수정한 데이터는 원래대로 되돌리도록 하겠습니다. 다음 포스트에서는 apollo federation에서의 인증과 인가를 적용하는 부분을 알아보도록 하겠습니다.

0개의 댓글