[8/11~12] 38, 39일차 회고록(Web Server 기초 1)

원지렁·2022년 8월 16일
0
post-thumbnail

오늘의 학습내용

1. CORS

1) CORS, SOP

1-1) SOP

Same-Origin Policy의 줄임말로, 보안상의 이유로 같은 출처의 리소스만 공유가 가능하다는 원칙임.

  • SOP 동일출처 범위
    : 프로토콜 + 호스트 + 포트

1-2) CORS

Cross-Origin Resource Sharing의 줄임말로, 교차 출처의 리소스를 공유할 수 있도록 하는 체제.

2) 동작 방식

2-1) 프리플라이트 요청 (Preflight Request)

실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처 리소스에 접근 권한이 있는지부터 확인하는 것
CORS에 대비가 되어있지 않은 서버를 보호할 수 있음.

2-2) 단순 요청 (Simple Request)

특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것

  • 조건
    GET, HEAD, POST 요청 중 하나여야 함.
    자동설정 헤더 외 Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정할 수 있음.
    Content-Type 헤더에는 application/x-www-form-urlencoded, multipart/form-data, text/plain 값만 허용됨.

2-3) 인증정보를 포함한 요청 (Credentialed Request)

요청 헤더에 인증 정보를 담아 보내는 요청
보안 정보가 포함되어 있기 때문에, 프론트/서버 양측 모두 CORS 설정이 필요함.

3) 설정 방법

3-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://domain.com");

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

3-1) Express

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

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

//특정 도메인
const options = {
  origin: "https://domain.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" });
});

2. Mini Node Server

대/소문자를 변환하여 출력하는 서버를 만들어보자

  • Express 리팩토링 ver.
const express = require('express');
const http = require('http');
const app = express();
const server = http.createServer(app);
const PORT = 4999;

// cors 설정
const cors = require('cors');
app.use(cors());

// Express 내장 미들웨어로 jsonParser 설정
const jsonParser = express.json({strict: false});

// POST메소드 설정 - lower
app.post('/lower', jsonParser, function (req, res, next) {
  res.json(req.body.toLowerCase()); 
  next(); // 다음 미들웨어 실행
})

app.post('/upper', jsonParser, function (req, res) {
  res.json(req.body.toUpperCase());
})

// 해당 PORT 서버 실행
server.listen(PORT,() => {
  console.log(`Server running on http://localhost:${PORT}`);
});

3. Refractor Express

1) Express

1-1) 설정 방법

  • 'Hello World' 출력
// terminal - npm install 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}`)
})
  • 라우팅 설정
const router = express.Router()

// get 메소드, 경로 설정
router.get('/lower', (req, res) => {
  res.send(data);
})

// post 메소드, 경로 설정
router.post('/lower', (req, res) => {
  // do something
})

2) Middleware

2-1) 사용 상황

  • POST 요청 등에 포함된 body(payload)를 구조화할 때
    : Node.js로 body를 받게되면 Buffer로 정보를 받아오기 때문에 이를 처리하는 과정이 다소 복잡함. 이때 body-parser 미들웨어를 사용하여 이를 단순화 할 수 있음. 나아가 express에서는 body-parser를 별도로 설치할 필요 없이 내장 미들웨어인 express.json()을 이용하여 이를 해결할 수 있음.

Node.js

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
});

Express

// {strict: false} --> strict: true일 경우 배열과 객체만 파싱 가능함
const jsonParser = express.json({strict: false});

// 메소드, 경로 설정 시 express.json 사용
app.post('/api/users', jsonParser, function (req, res) {

})
  • 모든 요청/응답에 CORS 헤더를 붙여야 할 때
    Node.js HTTP 모듈을 이용한 코드에 CORS 헤더를 붙이려면, 응답 객체의 writeHead 메서드를 이용해야하며 라우팅마다 헤더를 매번 작성하여야 함.

Node.js

const defaultCorsHeader = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Accept',
  'Access-Control-Max-Age': 10
};

// 생략
if (req.method === 'OPTIONS') {
  res.writeHead(201, defaultCorsHeader);
  res.end()
}

Express

// terminal - npm install cors설치

// 1. 모든 요청에 대해 CORS 허용
const cors = require('cors');

app.use(cors());

// 2. 특정 요청에 대해 CORS 허용
const cors = require('cors')

// 생략
app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})
  • 모든 요청에 대해 url이나 메서드를 확인할 때

app.use()
모든 요청에 동일한 미들웨어를 적용할 때 사용

const express = require('express');
const app = express();

const myLogger = function (req, res, next) {
  console.log('LOGGED');
  next();
};

// 모든 요청에 대해 myLogger 미들웨어 적용이 가능함.
app.use(myLogger);

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

app.listen(3000);
  • 요청 헤더에 사용자 인증 정보가 담겨있는지 확인할 때
    HTTP 요청에서 토큰이 있는지를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 미들웨어 예제
app.use((req, res, next) => {
  // 토큰이 있는지 확인, 없으면 받아줄 수 없음.
  if(req.headers.token){
    req.isLoggedIn = true;
    next();
  } else {
    res.status(400).send('invalid user')
  }
})
profile
새싹 개발자 지렁이의 벨로그입니다.

0개의 댓글