[SEB_FE_45] 2023.05.30 / Web Server 기초

Kay·2023년 5월 30일
0

CORS

CORS 등장배경 - SOP란?

SOP: Same-Origin Policy

같은 출처(Origin)의 리소스만 공유가 가능

* 출처(Origin): 프로토콜, 호스트, 포트의 조합

SOP는 잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여움

지도, AWS 기능 등 외부 API를 사용할 때 SOP에 해당하지 않지만 CORS를 통해 다른 출처의 리소스를 받아올 수 있음

CORS: Cross-Origin Resource Sharing

교차 출처 리소스 공유를 의미하며, 추가 HTTP 헤더를 사용하여 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여

CORS 동작 방식

  1. Preflight Request
    실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처 리소스에 접근 권한이 있는지부터 확인하는 것
  • 장점
    • 실제 요청을 보내기 전에 미리 권한 확인을 할 수 있기 때문에, 실제 요청을 처음부터 통째로 보내는 것보다 리소스 측면에서 효율적
    • CORS에 대비가 되어있지 않은 서버를 보호
  1. 단순요청
    특정 조건이 만족하면 프리플라이트(preflight) 요청을 생략하고 요청을 보냄
  • GET, HEAD, POST 요청 중 하나
  • 자동으로 설정되는 헤더 외에, Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정
    • Content-Type 헤더에는 application/x-www-form-urlencoded, multipart/form-data, text/plain 값만 허용
  1. 인증정보를 포함한 요청
    요청 헤더에 인증 정보를 담아 요청을 보냄
    클라이언트, 서버 둘 다 CORS 설정이 필요
  • 클라이언트: 요청 헤더에 withCredentials : true
  • 서버: 응답 헤더에 Access-Control-Allow-Credentials : true
    • 서버 측에서 Access-Control-Allow-Origin을 설정할 때, 모든 출처를 허용한다는 뜻의 와일드카드(*)로 설정하면 에러가 발생

인증 정보를 다루는 만큼 출처를 정확하게 설정해주어야 함

Express

Node.js로 쉽게 웹서버를 만들수 위도록 하는 라이브러리

  • 순수 Node.js 서버로 작성한 코드와 Express로 작성한 코드를 비교하면 다음과 같은 부분에서 코드 작성이 편안함을 알 수 있음!

유용한 Express의 미들웨어(Middleware)

use

// 전역 미들웨어: 모든 요청에 대해 실행되는 미들웨어
app.use((req, res, next) => {
  console.log('Global Middleware');
  next(); // 다음 미들웨어로 제어 전달
});

// 특정 경로에 대한 미들웨어
app.use('/api', (req, res, next) => {
  console.log('Middleware for /api');
  next();
});

// 라우터 등록
app.use('/api/users', userRouter);

1. POST 요청 등에 포함된 body(payload)

1) Node.js 서버 예시

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // body 변수에는 문자열 형태로 payload가 담겨져 있습니다.
});

2) Express 서버 예시
npm install body-parser

const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();

// 생략
app.post('/users', jsonParser, function (req, res) {

})

Express v4.16.0부터는 body-parser를 따로 설치하지 않고, Express 내장 미들웨어인 express.json()을 사용

2. CORS

1) Node.js 서버 예시

const http = require('http');

const server = http.createServer((request, response) => {
// 모든 도메인
  response.setHeader("Access-Control-Allow-Origin", "*");

// 특정 도메인
  response.setHeader("Access-Control-Allow-Origin", "https://codestates.com");

// 인증 정보를 포함한 요청을 받을 경우
  response.setHeader("Access-Control-Allow-Credentials", "true");
})

2) Express 서버 예시
npm install cors

const cors = require("cors");
const app = express();

//모든 도메인
app.use(cors());

//특정 도메인
const options = {
  origin: "https://codestates.com", // 접근 권한을 부여하는 도메인
  credentials: true, // 응답 헤더에 Access-Control-Allow-Credentials 추가
  optionsSuccessStatus: 200, // 응답 상태 200으로 설정
};

app.use(cors(options));

//특정 요청
app.get("/example/:id", cors(), function (req, res, next) {
  res.json({ msg: "example" });
});

3. 라우팅

1) Node.js 서버 코드 예시

const http = require('http');
const PORT = 4999;
const ip = 'localhost';

const server = http.createServer((request, response) => {
  if (request.method === "OPTIONS") {/* ... */}

  if (request.method === 'POST') {/* ... */}

server.listen(PORT, ip, () => {
  console.log(`http server listen on ${ip}:${PORT}`);
});

2) Express 서버 코드 예시

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

4. 토큰 확인

2) Express 서버 코드 예시

app.use((req, res, next) => {
  // 토큰이 있는지 확인, 없으면 받아줄 수 없음.
  if(req.headers.token){
    req.isLoggedIn = true;
    next();
  } else {
    res.status(400).send('invalid user')
  }
})

0개의 댓글