[node] CORS, mini node server

노호준·2023년 2월 6일
0

🦋 CORS

웹개발하면 CORS에러 겪음
CORS가 필요한 배경인 SOP를 먼저 알아보자

💡 SOP

Same-Origin Policy의 준말, 동일 출처 정책을 뜻함
즉 같은 출처의 리소스만 공유가 가능하다는 정책
여기서 출처는 다음과 같다.

출처는 프로토콜, 호스트, 포트의 조합인데 이중 하나라도 다르면 동일한 출처로 보지 않는다. 심지어 http:// https://도 다른것
SOP는 해킹등 위협에서 더 안전해지기 위해 만들어짐, 타 사이트와의 리소스공유를 제한함
하지만 다른출처의 리소스를 사용하고 싶을때는 어쩌지?

💡 CORS

Cross-Origin Resource Sharing
교차 출처 리소스 공유, 현 출처에서 실행중인 웹 어플이 다른 출처의 선택한 자원에 접근하는 권한을 부여하도록 브라우저에 알려주는 체제
크게 세가지 동작방식을 가짐
1. 프리플라이트 요청(Preflight Request)
실제 요청을 보내기 전, Option메서드로 사전 요청을 보내 해당 출처 리소스에 접근권한이 있는지 확인하는 것

응답헤더의 Acces-Control-Allow-Origin으로 돌아오면 실제 요청을 보내게됨

요청보낸 출처가 접근권한이 없다면 CORS에러 띄움
미리 권한확인 할수있어 실제요청을 통째로 보내는것보다 리소스측면에서 효율적

  1. 단순요청

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

  2. 인증정보를 포함한 요청
    요청 헤더에 인증정보를 담아 보내는 요청, 프론트, 서버 양측 모두 CORS설정이 필요함

CORS 설정방법

  1. Node.js 서버
    Node.js로 간단한 http서버를 만들경우 다음과 같이 응답헤더 설정가능
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");
})
  1. Express서버
    Express 프레임워크를 사용해서 서버를 만드는 경우에는, 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" });
});

mini node server

http요청을 처리하고 응답을 보내주는 프로그램을 웹 서버라 부름
이번에는 웹 서버를 만듭니다

터미널창에 node server/basic-server.js 치면
로컬호스트:5000으로 서버에 접속할수있다
get요청(브라우저에 그냥 치기)을 해볼수있다
localhost:5000/upper

if(메소드가 options) 프리프라이트리퀘스트 즉 cors설정을 돌려줘야 한다.
if(메소드가 post, url이 /upper면) 대문자로 응답을 돌려줘야한다
else if (메소드 post, url /lower) 소문자로 응답을 돌려줘야 한다
else 에러로 처리한다. 404 bad request

🦋 HTTP 트랜잭션 해부

  • 서버생성
    먼저 웹 서버 객체를 만들어야 함
const http = require('http');

const server = http.createServer((request, response) => {
  // 여기서 작업이 진행됩니다!
});

이 서버로 오는 HTTP 요청마다 createServer에 전달된 함수가 한번씩 호출된다.

const http = require('http');

const PORT = 4999;

const ip = 'localhost';

const server = http.createServer((request, response) => {

  if(request.method === 'OPTIONS') { //CORS
    response.writeHead(200, defaultCorsHeader);
    response.end();
  }

  if(request.method === 'POST' && request.url === '/upper'){
    let body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      body = Buffer.concat(body).toString().toUpperCase();
      response.writeHead(200, defaultCorsHeader);
      response.end(body);
    });
  }
  else if(request.method === 'POST' && request.url === '/lower'){
    let body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      body = Buffer.concat(body).toString().toLowerCase();
      response.writeHead(200, defaultCorsHeader);
      response.end(body);
    });
  }
  else {
    response.writeHead(404, defaultCorsHeader);
    response.end();

  }
  console.log(
    `http request method is ${request.method}, url is ${request.url}`
  );
});

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

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
};

실시간

  • 사실 http서버는 잘쓰지 않는다. 잘몰라도됨
  • CORS는 꼭 알아둬야한다. 프로젝트할때 항상 난리나는 부분이기 때문
  • 네트워크는 SOP정책이 있기때문에 출처가 같아야 에러가 안난다.
  • 프로토콜+호스트+포트
    1. 프리플라이트: 서버에게 미리하나 보내놓고 잘받으면 실제요청 보냄
    1. 단순요청은 3가지조건을 모두 만족해야만 pre-flight없이 그냥 요청 보내는데, 3가지 모두 만족하기가 쉽지 않다
    1. 사용자의 인증정보를 포함한 요청 : 대표적으로 사용자의 정보들 담은 쿠키가 있는데,
  • 서버객체, 서버리슨, 서버객체안에 response.end()만 있으면, http로 서버 만들수있심
  • 버튼을 누르면 프리플라이트가 먼저 날아가는걸 볼수있다.
  • 출처를 설정 헤더
  • 허용할 메서드를 설정 헤더
  • 허용할 헤더를 설정 헤더
  • 먼저 options로 날라오는 프리플라이트를 헤드를 설정해준다. (200, 404이런걸 지정해줄수있음)
  • response.end로 요청을 끝낼수 있다.
  • request에 on을 넣어서 이벤트를 설정해줄수 있음 addEventListner처럼
  • .on('data' 요청객체에 데이터가 있으니까 , (chunk)
  • 전달하고싶은 데이터를 청크라는 형태로 전달하는데, 청크를 버퍼라는 작은 상자에 저장해서 버퍼가 어느정도 찼다 싶으면 데이터를 전달한다. 이러한 과정을 스트림이라고 함
  • 청크를 푸쉬해서 [버퍼,버퍼,버퍼,버퍼]형태가 돼
  • class문법, this 잘 알아야함

this의 모든 경우

/ 1
// console.log(this); => window

// 2
// function a() {
//   console.log(this); => window
// }

// a();

// 3
const obj = {
  b: function () {
    console.log(this); => obj
  },
};

// obj.b();

// 4
// addEventListener => e.target

// 5
// class => 해당 클래스의 인스턴스

// 동적으로 변하는 this 고정 => bind

const a = function () {
  console.log(this);
};

a();

const b = a.bind({ d: 1234 });
b();

this암기한다 > bind를통해서 this고정 > 클래스, 프로토타입

0개의 댓글

관련 채용 정보