CORS에 들어가기 전에..
: Same-Origin Policy의 줄임말로 동일 출처 정책을 뜻한다.
https://www.codestates.com
vs http://www.codestates.com
https://urclass.codestates.com
vs https://codestates.com
http://codestates.com:81
vs http://codestates.com
80
https://codestates.com:443
vs https://codestates.com
443
➡️ 다른 출처의 리소스를 받아오기 위해 필요한 것이 바로 "CORS"
Cross-Origin Resource Sharing 의 줄임말로 교차 출처 리소스 공유를 뜻한다.
추가 HTTP 헤더를 사용하여, 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여
MDN정의
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS) 는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다.
즉, 브라우저는 SOP에 의해 기본적으로 다른출처의 리소스 공유를 막지만, CORS를 사용하여 접근 권한을 얻을 수 있는 것
위 에러를 해석해보면
다른 출처의 리소스를 가져오려 했으나, SOP 때문에 접근이 불가능 하다.
CORS 설정을 통해 서버의 응답 헤더에 'Access-Control-Allow-Origin'을 작성하면 접근 권한을 얻을 수 있다.
➡️ 위 에러는 CORS 때문이 아닌 "SOP"에 의해 막힌것 ! CORS는 오히려 이 에러를 해결해 줄 수 있는 해결방안임 👍🏻
CORS의 동작 방식에는 크게 3가지가 있다.
➡️ 실제 요청을 보내기 전 , OPTIONS 메서드로 사전요청을 보내 해당 출처 리소스에 접근 권한이 있는지 확인하는 것
Access-Control_Allow-Origin
으로 요청을 보낸 출처가 돌아오면 실제 요청을 보내게 된다.➡️ 브라우저는 실제요청을 서버에 전달하지 않고 CORS 에러를 전달해줌 ! ( 🖥️ : 너 권한 없어 )
실제 요청을 보내기 전 미리 권한 Check 가능
➡️ 실제 요청을 다짜고짜 보내는 것 보다 리소스 측면에서 GOOD 👍🏻
CORS가 대비되지 않은 서버를 보호할 수 있음
➡️ 이전에 만들어진 서버들은 SOP 요청만 들어오는 상황을 고려하고 만들어짐
➡️ 따라서 다른 출처에서 들어오는 요청에 대한 대비 X
이런 서버에 요청 전송 ➡️ 응답을 보내기 전 우선 요청을 처리하게 된다.
브라우저는 응답을 받은 후에서야 CORS 권한이 없다는 것을 인지..
➡️ 에러를 받은 시점은 이미 요청이 수행된 상태
( DELETE
나 PUT
처럼 서버의 정보를 수정,삭제하는 요청이라면 아찔..😵💫 )
하지만 CORS에 대비가 되어있지 않은 서버라도 프리플라이트 요청을 먼저 보내면 CORS에러를 띄우게 된다 !
➡️ 특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것
GET
, HEAD
, POST
요청 중 하나일 것Accept
, Accept-Language
, Content-Language
, Content-Type
헤더의 값만 수동으로 설정할 수 있음Content-Type
헤더에는 application/x-www-form-urlencoded
, multipart/form-data
, text/plain
값만 허용➡️ 요청 헤더에 인증정보를 담아내는 요청
- 프론트 : 요청헤더에
withCredentials : true
를 넣어줘야함- 서버 :
Access-Control-Allow-Credentials : true
를 넣어줘야 함- 서버 측에서
Access-Control-Allow-Origin
을 설정할 때,
모든 출처를 허용한다는 뜻의 와일드카드 (*) 로 설정하면 에러 발생
➡️ 인증정보를 다루는 만큼 출처를 명확하게 표시해야함
➡️ 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");
➡️ Express 프레임워크를 사용해서 서버를 만드는 경우, cors 미들웨어를 사용하여 더욱 간단하게 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"});
});