반응형

 

📝인증 및 인가

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { GraphQLError } from 'graphql';

interface MyContext {
  user: UserInterface;
}

const server = new ApolloServer<MyContext>({
  typeDefs,
  resolvers,
});

const { url } = await startStandaloneServer(server, {
  
  context: async ({ req }) => {
    // get the user token from the headers
    const token = req.headers.authorization || '';

    // try to retrieve a user with the token
    const user = getUser(token);

    // optionally block the user
    // we could also check user roles/permissions here
    if (!user)
      // throwing a `GraphQLError` here allows us to specify an HTTP status code,
      // standard `Error`s will have a 500 status code by default
      throw new GraphQLError('User is not authenticated', {
        extensions: {
          code: 'UNAUTHENTICATED',
          http: { status: 401 },
        },
      });

    // add the user to the context
    return { user };
  },
  
});

console.log(`🚀 Server listening at: ${url}`);

Apollo Server에서는 contextValue라는 걸 제공하는데 헤더에 대한 정보를 추출할 수 있습니다 이걸 이용해 인증 및 인가에 대한 처리가 가능합니다

 

const resolvers = {
  Query: {
    adminData: (parent, args, context) => {
      if (!context.user || context.user.role !== 'ADMIN') {
        throw new AuthenticationError('You must be an admin to view this data');
      }

      return "This is private data only for administrators.";
    }
  }
};

Resolver에서도 가능합니다

 

const typeDefs = `#graphql
  directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION

  enum Role {
    ADMIN
    REVIEWER
    USER
  }

  type User @auth(requires: USER) {
    name: String
    banned: Boolean @auth(requires: ADMIN)
    canPost: Boolean @auth(requires: REVIEWER)
  }
`;

Directive로 설정도 가능합니다

 

자세한 건 공식 문서를 참고바랍니다

https://www.apollographql.com/docs/apollo-server/security/authentication

 

📝CORS

CORS 설정이 기본적으로 되어있다 
자세한 건 공식 문서를 참고바랍니다

https://www.apollographql.com/docs/apollo-server/security/cors

 

📝SSL

import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import typeDefs from './graphql/schema';
import resolvers from './graphql/resolvers';
import cors from 'cors';
import express from 'express';
import http from 'http';
import https from 'https';
import fs from 'fs';

const configurations = {
  // Note: You may need sudo to run on port 443
  production: { ssl: true, port: 443, hostname: 'example.com' },
  development: { ssl: false, port: 4000, hostname: 'localhost' },
};

const environment = process.env.NODE_ENV || 'production';
const config = configurations[environment];

const server = new ApolloServer({
  typeDefs,
  resolvers,
});
await server.start();

const app = express();
// our express server is mounted at /graphql
app.use('/graphql', cors<cors.CorsRequest>(), express.json(), expressMiddleware(server));

// Create the HTTPS or HTTP server, per configuration
let httpServer;
if (config.ssl) {
  // Assumes certificates are in a .ssl folder off of the package root.
  // Make sure these files are secured.
  httpServer = https.createServer(
    {
      key: fs.readFileSync(`./ssl/${environment}/server.key`),
      cert: fs.readFileSync(`./ssl/${environment}/server.crt`),
    },

    app,
  );
} else {
  httpServer = http.createServer(app);
}

await new Promise<void>((resolve) => httpServer.listen({ port: config.port }, resolve));

console.log('🚀 Server ready at', `http${config.ssl ? 's' : ''}://${config.hostname}:${config.port}/graphql`);

 

SSL 설정을 프로뎍선 레벨과 개발 레벨로 나눌 수 있다

 

자세한 건 공식 문서를 참고바랍니다
https://www.apollographql.com/docs/apollo-server/security/terminating-ssl

 

📝Proxy (프록시)

나가는 요청등에 대한 프록시 설정이 가능한데 자세한 건 문서를 참고바랍니다
https://www.apollographql.com/docs/apollo-server/security/proxy-configuration

 

📝클라우드 서버 배포 (Lambda, Heroku)

클라우드 서버에 가장 많이 배포하는 유형에 대한 설명이 있습니다 AWS의 Lambda와 Heroku가 있으니 자세한건 문서 참고 바랍니다
https://www.apollographql.com/docs/apollo-server/deployment/lambda
https://www.apollographql.com/docs/apollo-server/deployment/heroku

 

📝로깅 (Logging)

GRAPH OS라는 제품을 제공하는데 이걸 이용해 로깅을 따로 집계하고 통계를 내는 등에 역할을 도와줍니다

 

const myPlugin = {
  // Fires whenever a GraphQL request is received from a client.
  async requestDidStart(requestContext) {
    console.log('Request started! Query:\n' + requestContext.request.query);

    return {
      // Fires whenever Apollo Server will parse a GraphQL
      // request to create its associated document AST.
      async parsingDidStart(requestContext) {
        console.log('Parsing started!');
      },

      // Fires whenever Apollo Server will validate a
      // request's document AST against your GraphQL schema.
      async validationDidStart(requestContext) {
        console.log('Validation started!');
      },
    };
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [myPlugin],
});

또한 사용자 정의 플러그인을 이용해 세분화된 작업 로깅을 설정할 수 있습니다

자세한 사항은 공식 문서를 참고바랍니다
https://www.apollographql.com/docs/apollo-server/monitoring/metrics

반응형