cors란
Cross Origin Resource Sharing의 약자
클라이언트와 다른 origin을 가진 서버가 서로 통신할 수 있도록 허용하는 프로토콜이다.
자신이 속하지 않는 다른 도메인, 다른 프로토콜, 다른 포트에 있는 리소스를 요청하는 cross-origin HTTP 요청 방식이다.
기본적으로 도메인 혹은 포트가 다른 클라이언트가 서버에 api요청을 보냈을 때,
브라우저가 보안상의 이유로 api를 차단한다.
이를 cors를 통해 허용하여 정상적인 api요청을 주고받을 수 있도록 한다.
즉, cors를 설정하지 않으면 기본적으로 허용하지 않은 다른 도메인, 다른 포트로부터의 api요청은 받을 수 없다.
왜냐하면, 특정 서버 리소스에 다른 임의의 웹 사이트들이 api 요청을 보내서 악의적으로 특정 서버의 세션을 탈취하거나, 서버에 무리가 가는 행동, 사용자의 정보 등을 가져가는 등 문제가 생길 수 있는 행위를 할 수 있기 때문이다.
그러기 때문에 cors로 허용한 도메인과 포트를 사용한 api요청에만 응답을 해주어 보안을 강화한다.
왼쪽의 웹은 domain-a.com으로 (서버 A)로 구동되고 있다.
파란색 이미지는 웹 사이트가 구동 중인 domain과 동일 한 domain-a.com(서버 A)로부터 자료를 요청하고 수신한다.
빨간색 이미지는 domain-b.com(서버 B)라는 도메인에 자료를 요청하고 수신한다.
서버는 기본적으로 cors 방식을 제한해둔다. 즉, 보안상의 이유로 사용하지 못하게 한다.
그러므로 다른 사이트에서 나의 서버에 요청하는 것을 허용하고 싶다면, 모두에게 제한 없이 제공하는 방식이나 본인이 직접 특정 도메인들만을 허용하여 접근할 수 있도록 해준다.
cors 모듈 사용
설치
npm i cors
- 모두에게 허용하는 방법
// app.js
const express = require("express");
const port = 3000
const app = express();
const cors = require("cors");
app.use(cors());
app.use(express.json());
app.get("/", (req, res) => {
res.status(200).json({ massage: "연동 잘 됨." });
});
app.listen(port, () => {
console.log(port, "포트로 서버가 열렸어요!");
});
cors 모듈을 불러오고
app.use(cors()) 를 사용해 모든 도메인에서 제한 없이 해당 서버에 요청을 보내고 응답을 받을 수 있다.
- 특정 도메인만 허용하는 방법
// app.js
const express = require("express");
const port = 3000
const app = express();
const cors = require("cors");
const corsOptions = {
origin: 'https://www.domain.com',
credentials: true // 사용자 인증(쿠키) 주고 받기 허용
// methods: [‘GET’, ‘POST’, ‘DELETE’, ‘PUT’] // 특정 메서드만 허용할 수도 있음
}
app.use(cors(corsOptions));
app.use(express.json());
app.get("/", (req, res) => {
res.status(200).json({ massage: "연동 잘 됨." });
});
app.listen(port, () => {
console.log(port, "포트로 서버가 열렸어요!");
});
corsOptions 변수에 허용할 도메인을 추가하고,
app.use(cors(corsOptions))를 통해 특정 도메인만의 접근만 허용해서 서버에 요청과 응답을 주고받을 수 있다.
사용자 인증(쿠키) 요청 허용 방법(클라이언트 서버 둘다 적용해야함)
- 클라이언트
// 클라이언트
fetch('http://localhost:3001/cors', {
method: 'PUT',
credentials: 'include' // credentials 옵션
})
.then(function(response) { ... })
.catch(function(error) { ... })
클라이언트가 axios인 경우
// 1. axios 전역 설정
axios.defaults.withCredentials = true; // withCredentials 전역 설정
// or
// 2. axiod 옵션 객체로 넣기
axios.post(`${EndPoint.APIServer}/myauth/login/`, {
profile: { username: username, password: password }
}, {
withCredentials: true // 쿠키 cors 통신 설정
})
.then(response => {
console.log(response);
console.log(response.data);
})
-서버
// 서버
const express = require('express')
const cors = require('cors');
const app = express();
app.use(cors({
origin: '*', // 출처 허용 옵션
credential: 'true' // 사용자 인증이 필요한 리소스(쿠키 ..등) 접근
}));
...라우터
도메인이 다른 클라이언트가 쿠키 값을 보내고 싶으면, 클라이언트에선 credentials: 'include' 옵션 설정을 넣어주어야 한다.
서버에서도 credentials: true 옵션을 넣어 둘 다 설정해주어야 한다.
credentials: true 옵션은 다른 도메인 간에 쿠키 공유를 허락하는 옵션
(도메인이 다른 경우 이 옵션이 비활성화 라면 로그인이 되지 않을 수 있다.)
cors 모듈을 사용하지 않는 방법
app.get('/', (req,res) => {
res.header("Access-Control-Allow-Origin", "*");
...
}
'coding > Node.js' 카테고리의 다른 글
비밀번호 암호화 - bcrypt (0) | 2022.08.17 |
---|---|
swagger 설치 및 설정 기본 사용법 (0) | 2022.08.17 |
Sequelize 시작, migrate 사용 관계 설정 (0) | 2022.08.13 |
node.js Controller, Service, Repository (1) | 2022.08.07 |
계층형 아키텍처 패턴(Layered Architecture Pattern) (0) | 2022.08.05 |