티스토리 뷰
CORS란?
Cross-Origin Resource Sharing - 다른 출처의 리소스를 공유하는 것을 브라우저가 막는 보안 정책
출처(Origin)란?
- 프로토콜, 도메인, 포트 세 가지 중 하나라도 다른 경우 다른 출처
https://example.com:3000/api/users
└─┬─┘ └────┬────┘ └┬┘
프로토콜 도메인 포트
왜 CORS 에러가 날까?
- CORS는 브라우저의 정책으로, Postman이나 서버에서는 문제 없이 동작
// 브라우저에서 실행
fetch('https://api.example.com/data')
.then(res => res.json())
.then(console.log);
// CORS 에러!
// Access to fetch at 'https://api.example.com/data' from origin
// 'https://myapp.com' has been blocked by CORS policy
해결 방법
1. 서버에서 CORS 허용 (정석)
const express = require('express');
const cors = require('cors');
const app = express();
// 모든 출처 허용 (개발용)
app.use(cors());
// 특정 출처만 허용 (프로덕션)
app.use(cors({
origin: 'https://myapp.com',
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
직접 헤더 설정
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://myapp.com');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
// Preflight 요청 처리
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
2. 개발 환경에서 프록시 사용
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
// 이제 /api/users로 요청하면 https://api.example.com/users로 전달
fetch('/api/users'); // CORS 문제 없음
// nuxt.config.js
export default defineNuxtConfig({
nitro: {
devProxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true
}
}
}
})
자주 하는 실수
1. * 와 credentials 함께 사용
// 에러 발생
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true');
// 특정 도메인 명시
res.header('Access-Control-Allow-Origin', 'https://myapp.com');
res.header('Access-Control-Allow-Credentials', 'true');
2. Preflight 요청 처리 X
// OPTIONS 요청 처리 안 함
app.post('/api/users', (req, res) => {
// POST만 처리
});
// OPTIONS 요청도 처리
app.options('/api/users', (req, res) => {
res.sendStatus(200);
});
app.post('/api/users', (req, res) => {
// POST 처리
});
'ETC' 카테고리의 다른 글
| Mac - 연속 입력 (반복키) 활성화 (0) | 2026.03.30 |
|---|---|
| Nginx 로컬 개발 환경 프록시 설정 (0) | 2026.02.04 |
| [Mac] IntelliJ에서 왼쪽 클릭이 안되는 문제 (0) | 2024.05.16 |
| Docker Image 사이즈 줄이기 (멀티 스테이지 빌드) (0) | 2024.03.22 |
| Docker Desktop 대체 (MAC) (0) | 2024.03.20 |