개발일지

개발일지 5주차 WIL

index.ys 2023. 5. 7. 20:05

CORS (Cross Origin Resource Sharing)

  • 교차 출처 리소스 공유 정책
  • 출처가 다른 리소스끼리 공유가 가능하게 전제함

SOP

  • 동일 출처 정책
  • SOP는 동일한 출처에만 리소스를 공유할 수 있음을 전제함
  • SOP는 동일한 출처(프로토콜 + 도메인 + 포트번호)에 있는 리소스만 가져올 수 있음을 의미

CORS에러 발생원인

  • 자바스크립트는 기본적으로 SOP정책을 따르기 때문에 fetch, axios로 다른 출처가 다른 서버에 요청을 보냈을때 브라우저에서 응답값의 출처를 확인한후 출처가 다를 경우 CORS에러 발생
  • api를 요청한 클라이언트의 출처(origin)과 요청을 받는 서버의 출처(origin)이 다를떄 CORS에러 발생
  • 서버에서 온 응답을 브라우저에서 확인하고 응답을 분석하여 출처(origin)가 다를때 브라우저에서 요청을 막음

출처(Origin)

  • 클라이언트의 프로토콜, 도메인,포트번호와 서버의 프로토콜, 도메인,포트번호 가 같을때 출처가 같다
  • 자바스크립트에서 현재 사이트의 origin을 알아내는 코드
console.log(location.origin); // "https://www.naver.com" (포트 번호 80번은 생략됨)

출처 비교 기준

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F#thankYou

 

  • Protocol(Schema): http, https
  • Host : 사이트 도메인
  • Port : 포트번호
  • Path : 사이트 내부 경로
  • Query string 요청의 key와 value
  • Fragment: 해시 태그

CORS 에러 발생시켜보기

  • index.html에서 fetch로 localhost:3000으로 요청시 출처가 달라 CORS에러를 발생시키고 Access-Control-Allow-Origin의 헤더가 다르다는 에러 반환

해결방법

서버에서 Access-Controll-Allow-Oringin 헤더 세팅

# 헤더에 작성된 출처만 브라우저가 리소스를 접근할 수 있도록 허용함.
# * 이면 모든 곳에 공개되어 있음을 의미한다. 
Access-Control-Allow-Origin : https://naver.com

# 리소스 접근을 허용하는 HTTP 메서드를 지정해 주는 헤더
Access-Control-Request-Methods : GET, POST, PUT, DELETE

# 요청을 허용하는 해더.
Access-Control-Allow-Headers : Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization

# 클라이언트에서 preflight 의 요청 결과를 저장할 기간을 지정
# 60초 동안 preflight 요청을 캐시하는 설정으로, 첫 요청 이후 60초 동안은 OPTIONS 메소드를 사용하는 예비 요청을 보내지 않는다.
Access-Control-Max-Age : 60

# 클라이언트 요청이 쿠키를 통해서 자격 증명을 해야 하는 경우에 true. 
# 자바스크립트 요청에서 credentials가 include일 때 요청에 대한 응답을 할 수 있는지를 나타낸다.
Access-Control-Allow-Credentials : true

# 기본적으로 브라우저에게 노출이 되지 않지만, 브라우저 측에서 접근할 수 있게 허용해주는 헤더를 지정
Access-Control-Expose-Headers : Content-Length

Node에서 express로 cors헤더 셋팅하기

직접 헤더에 명시

res.setHeader('Access-Control-Allow-origin', '*');
res.setHeader('Access-Control-Allow-Credentials', 'true'); // 쿠키 주고받기 허용

res.end();

CORS 미들웨어 사용

  • cors 패키지 설치
> npm i cors
  • origin: 허용출처 설정
  • credential: 다른 도메인 간에 쿠키 공유를 허락하는 옵션
const express = require('express')
const cors = require('cors');

const app = express();

app.use(cors({
    origin: true, // 출처 허용 옵션
    credential: true // 사용자 인증이 필요한 리소스(쿠키 ..등) 접근
}));
  • DB에서 등록된 도메인인지 조회
  • 만약 등록된 도메인이라면, 클라이언트에서 보낸 origin을 허용하게 설정 origin : req.get('origin')
//* cors 전용 라우터
router.use(async (req, res, next) => {
   // api서버로부터 발급받은 허용된 사용자인지 DB로 체크
   const domain = await Domain.findOne({
      where: { host: new URL(req.get('origin'))?.host }, // 브라우저에서 요청 헤더에 origin을 넣어서 보낸걸 받는다.
   });

   if (domain) {
      // 만약 api서버로부터 발급받은 허용된 사용자라면, cors 설정해주기
      cors({
         origin: req.get('origin'), // origin : true 모두 허용하면 보안상 위험하니까
         credentials: true, // 쿠키 통신 설정 : 인증된 요청
      })(req, res, next); //? 미들웨어 확장 패턴 : 그냥 router.use(cors()) 이렇게 쓰지말고 조건에 따라 미들웨어가 실행괴게 할 수 있다.
   } else {
      next(); // 만일 등록된 도메인이 아니라면 그대로 보내줘서 cors 에러뜨게 놔둔다.
   }
});

참고블로그:

https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-CORS-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0-cors-%EB%AA%A8%EB%93%88#2._cors_%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4_%EC%82%AC%EC%9A%A9

 

[NODE] 📚 cors 모듈 - CORS 간편 설정하기

CORS 허용 설정 하는 방법 Node.js 서버 프로젝트에서 cors(cross origin resource sharing) 문제를 해결하는 방법은 크게 2가지가 있다. 하나는 직접 헤더를 명시해서 출처(origin)을 필터링하는 것이고, 다른

inpa.tistory.com