본문 바로가기
Error

Axios CORS 에러

by eddypark 2023. 8. 25.

CORS(Cross Origin Resource Sharing)란?

현재 웹페이지 도메인에서 다른 웹페이지 도메인으로 리소스가 요청되는 경우를 말한다.

ex) 클라인트 서버 : http://localhost:3000 => API 서버 : http://localhost:8080 API를 요청하면

http 형태로 요청이 되므로 브라우저 자체에서 보안 상 이유로 CORS를 제한하게 되는 현상

오류 발생이유

기본적으로 브라우저가 제공하는 요청 API 들은 별도의 옵션 없이 브라우저의 쿠키와 같은 인증과 관련된 데이터를 함부로 요청 데이터에 담지 않도록 되어있다. 이는 응답을 받을때도 마찬가지이다.

그러니까 위와 같이 프론트와 백엔드 서버의 Origin이 다를 경우, 백엔드에서 프론트엔드로 쿠키를 생성해줄 수도, 프론트엔드에서 백엔드로 쿠키를 보내줄 수도 없는 것이다.

따라서 요청과 응답에 쿠키를 허용하고 싶을 경우, 이를 해결하기 위한 옵션이 바로 withCredentials 옵션이다.

* withCredentials 옵션이란 다른 도메인에 요청을 보낼때 요청에 인증 정보를 담는 옵션이다.

해결방법

- 클라이언트에서 처리하는 경우 안 되는 케이스도 있어서 가능하면 서버에서 처리하는 방법이 안전하다.

1. 클라이언트 처리

(1) axios 설정

    ① axios 전역 설정

axios.defaults.withCredentials = true; // withCredentials 전역 설정

 

    ② axios 옵션 객체로 넣기

axios.post(
	'https://example.com:1234/users/login',
    { profile: { username: username, password: password } },
    { withCredentials: true }
).then(response => {
	console.log(response);
    console.log(response.data); 
})

 

(2) fetch 설정

fetch("https://example.com:1234/users/login", { 
	method: "POST",
    credentials: "include", // 클라이언트와 서버가 통신할때 쿠키 값을 공유하겠다는 설정 
})
 

(3) jQuery 설정

$.ajax({ 
	url: "https://example.com:1234/users/login",
    type: "POST", 
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    xhrFields: {
    	withCredentials: true // 클라이언트와 서버가 통신할때 쿠키 값을 공유하겠다는 설정 
    }, 
    success: function (retval, textStatus) {
    	console.log( JSON.stringify(retval)); 
    } 
    error: function () { 
    	console.log("error"); 
    } 
 });
 

(3) XMLHttpRequest 객체

const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
 

2. 서버 처리

(1) Node.js 서버 설정

var http = require('http');

const PORT = process.env.PORT || 3000;

var httpServer = http.createServer(function (request, response) {
    // Setting up Headers
    response.setHeader('Access-Control-Allow-origin', '*'); // 모든 출처(orogin)을 허용
    response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // 모든 HTTP 메서드 허용
    response.setHeader('Access-Control-Allow-Credentials', 'true'); // 클라이언트와 서버 간에 쿠키 주고받기 허용

    // ...

    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.end('ok');
});

httpServer.listen(PORT, () => {
    console.log('Server is running at port 3000...');
});

 

(2) Express.js 서버 설정

> npm install cors  // cors 깔려있어야함
const express = require('express')
const cors = require('cors');

const app = express();

app.use(cors({
    origin: '*', // 출처 허용 옵션
    credential: 'true' // 사용자 인증이 필요한 리소스(쿠키 ..등) 접근
}));
 
 

(3) Spring 서버 설정

// 스프링 서버 전역적으로 CORS 설정
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        	.allowedOrigins("http://localhost:8080", "http://localhost:8081") // 허용할 출처
            .allowedMethods("GET", "POST") // 허용할 HTTP method
            .allowCredentials(true) // 쿠키 인증 요청 허용
            .maxAge(3000) // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
    }
}

 

 

[출처] https://inpa.tistory.com/entry/AXIOS-%F0%9F%93%9A-CORS-%EC%BF%A0%ED%82%A4-%EC%A0%84%EC%86%A1withCredentials-%EC%98%B5%EC%85%98