Node.js

Node에서 API 서버 만들기

쿠와와 2021. 1. 8. 14:01

크롤링은 서버에 부담을 많이 일으킨다. 잘못하면 디도스 공격이 될 수도 있다. -> API를 제공하는 것이 좋다. 

API 서버 이해하기

NodeBird SNS 서비스

API: Application Programming Interface

  • 다른 애플리케이션에서 현재 프로그램의 기능을 사용할 수 있게 함
  • API : 다른 웹 서비스의 기능을 사용하거나 자원을 가져올 수 있게 함
  • 다른 사람에게 정보를 제공하고 싶은 부분만 API를 열고, 제공하고 싶지 않은 부분은 API를 만들지 않으면 됨
  • API에 제한을 걸어 일정 횟수 내에서만 가져가게 할 수도 있음
  • NodeBird에서는 인증된 사용자에게만 정보 제공

2개로 나뉜 이유? -> API서버가 터져도 서비스를 가동해주기 위해

내 애플리케이션을 제공 및 관리, 통제 가능

 

nodebird-api 폴더를 만들고 package.json 생성

  • 생성 후 npm i 패키지 설치
  • NodeBird에서 config, models, passport 모두 복사해서 nodebird-api에 붙여넣기
  • routes 폴더에서는 auth.jsmiddlewares 재사용
  • .env 파일 복사
  • views 폴더를 만들고 error.html 파일 생성

 

app.js 생성하기

 

8002번 포트 사용

  • 8001번을 사용하는 NodeBird 서비스와 8003을 사용할 nodecat 서비스와 함께 사용할 수 있음
  • 콘솔을 여러 개 실행해 각각의 서비스를 돌리면 됨

 

nodebird-api/views/login.html 화면 생성

  • NodeBird 서비스의 계정으로 로그인하면 됨(카카오톡 로그인은 안 됨)

 

도메인 모델 생성하기

models/domain.js 작성

  • API를 사용할 도메인(또는 호스트)을 저장하는 모델
  • ENUM type으로 freepremium 쓸 수 있게 제한
  • clientSecretuuid 타입으로
const Sequelize = require('sequelize');

module.exports = class Domain extends Sequelize.Model {
  static init(sequelize) {
    return super.init({
      host: {
        type: Sequelize.STRING(80),
        allowNull: false,
      },
      type: {
        type: Sequelize.ENUM('free', 'premium'),
        allowNull: false,
      },
      clientSecret: {
        type: Sequelize.STRING(36),
        allowNull: false,
      },
    }, {
      sequelize,
      timestamps: true,
      paranoid: true,
      modelName: 'Domain',
      tableName: 'domains',
    });
  }

  static associate(db) {
    db.Domain.belongsTo(db.User);
  }
};

 

도메인 등록 라우터

routes/index에서 도메인 등록 라우터 생성

  • uuid 패키지로 사용자가 등록한 도메인에 고유한 비밀번호 부여
  • uuid는 충돌(고유하지 않은 상황) 위험이 있지만 매우 희박
  • 비밀번호가 일치하는 요청만 API 응답
const express = require('express');
const { v4: uuidv4 } = require('uuid');
const { User, Domain } = require('../models');
const { isLoggedIn } = require('./middlewares');

const router = express.Router();

router.get('/', async (req, res, next) => {
  try {
    const user = await User.findOne({
      where: { id: req.user && req.user.id || null },
      include: { model: Domain },
    });
    res.render('login', {
      user,
      domains: user && user.Domains,
    });
  } catch (err) {
    console.error(err);
    next(err);
  }
});

router.post('/domain', isLoggedIn, async (req, res, next) => {
  try {
    await Domain.create({
      UserId: req.user.id,
      host: req.body.host,
      type: req.body.type,
      clientSecret: uuidv4(),
    });
    res.redirect('/');
  } catch (err) {
    console.error(err);
    next(err);
  }
});

module.exports = router;

 

 

도메인 등록하고 비밀번호 발급받기

 

라우터 작성 후 localhost:8002 접속

  • 도메인이 다른 프런트엔드에서 요청을 보내면 CORS 에러(10.7) 발생
  • 로그인 후 localhost:8003(nodecat 서버) 등록