Skip to content

Backend 학습정리

정수원 edited this page Dec 15, 2020 · 4 revisions
1. Mongoose

Mongoose

  • MongoDB를 이용한 객체 모델링을 제공하는 NPM 모듈 및 ODM (Object Document Modeling/Mapping)
  • promise, callback 을 자유자재로 전환할 수 있다. (?)
  • 자체 검증(validation)과 타입 변환이 가능

schema

  • MongoDB는 테이블이 없기 때문에 아무 데이터나 넣어도 에러가 나지 않기 때문에 문제가 생길 수 있다.
  • 이러한 문제를 막기 위해 몽구스는 스키마를 도입했다.
  • 스키마를 기준으로 DB에 데이터를 넣기 전에 먼저 검사한다. → 스키마에 어긋나면 에러 발생
  • 작성된 스키마를 독립적인 모델로 관리할 수 있다.
  • 스키마 수정이 쉽다.

vs Graphql의 schema

  • 데이터 타입을 정의 → 가져올 데이터의 형태
  • mongoose의 스키마와 비슷한 구조
  • 쿼리가 실행될 때마다 타입 시스템에 기초하여 쿼리가 유효한지 검사한다.
2. AuthDirective

1. directives.ts

class AuthDirective extends SchemaDirectiveVisitor {
    1) 해당 페이지에서 요구되는 타입 확인 (requires)
    2) 해당 페이지에서 요구되는 타입(User or Driver)의 토큰을 가져온다. (userToken, driverToken)
    	1-1) 토큰이 없으면 인증 x
    3) 토큰을 복호화한 후 사용자를 조회 (인증) 
    	2-1) 조회 결과 없으면 인증 x
    4) 인증이 되면, 인증 성공

2. app.ts

const apolloServer = new ApolloServer({
    schemaDirectives: {
    	 auth: AuthDirective
    }
})

3. schema.ts

directive @auth(requires: Role!) on FIELD_DEFINITION

@auth로 사용가능

4. front에서 라우팅 처리

  • 인증을 두번 해야하는 경우
ex) 
type Query {
    users: String
    isAuthorizedUser: Boolean 
     	@hasRole(roles: [THIS_ADMIN, THIS_SUPER_ADMIN] @auth(requires: USER)
        // auth가 먼저 실행되고 hasRole이 실행됨 -> 오른쪽부터 왼쪽으로
}

5. 적용 결과

import { SchemaDirectiveVisitor } from 'apollo-server-express';
import { defaultFieldResolver } from 'graphql';
import jwt from 'jsonwebtoken';
import Config from '../../config';

class AuthDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field) {
    const requiredRole = this.args.requires;
    const isDriverAuth = requiredRole === 'DRIVER';
    const { resolve = defaultFieldResolver } = field;
    // resolve: isAuthorizedUser / isAuthorizedDriver

    field.resolve = async (...args) => {
      try {
        const { req, res, dataSources } = args[2]; // context
        const [token, type] = isDriverAuth
          ? [req.signedCookies.driverToken, 'Driver']
          : [req.signedCookies.userToken, 'User'];
        if (!token) throw new Error('Unauthorized access'); // 인증 실패 시 처리 -> catch (err)

        const decoded = jwt.verify(token, Config.JWT_SECRET);
        const model = dataSources.model(type);
        const result = await model.findOne({ _id: decoded.id });
        if (result) return resolve.apply(this, args);
        else {
          throw new Error('You must be the authenticated');
        }
      } catch (err) {
        // 인증 실패 시 로직
      }
    };
  }
}
export default AuthDirective;
3. mongoDB notion-mongoDB
4. NoSQL notion-NoSQL
5. GraphQL notion-GraphQL