카테고리 없음

CORS 에 대하여 알아봅시다 (official DOC)

lluna 2022. 2. 4. 12:06

CORS (Cross-Origin Resource Sharing) 교차 출처 리소스 공유

주어진 도메인 외부에 있는 리소스에 대한 제어된 액세스를 가능하게 하는 브라우저 매커니즘입니다.

이는 동일 출처 정책 (SOP)를 확장하고 유연성을 추가한 것입니다.

 

SOP(Same-Origin Policy) 동일 출처 정책이란?

동일 출처 정책은 웹사이트가 서로를 공격하는 것을 방지하기 위한 웹브라우저 보안 매커니즘입니다.

출처는 Origin 입니다. 

한 출처의 스크립트가 다른 출처의 데이터에 액세스하지 못하도록 제한합니다.

 

Origin 이라는 용어를 이해해봅시다. Origin은 프로토콜, 주소, 포트번호의 쌍을 말합니다.

여기에서 포트 번호는 생략 가능합니다. 생략하면 HTTP 방식으로 오면 80, HTTPS 방식으로 오면 443 포트를 이용하게 됩니다.

다른 Origin 이라고 하면 프로토콜이나 주소나, 포트번호 중 하나라도 다른 것입니다.

Origin = [프로토콜]://[Host의 IP 주소 또는 URL]:[포트번호]

예시를 들어 보겠습니다. Origin 예시입니다.

http://normal-website.com/example/example.html 

각각 액세스를 허용하는지 살펴봅시다.

주소 허용 여부
http://normal-website.com/example/ 예: 동일한 체계, 도메인 및 포트
http://normal-website.com/example2/ 예: 동일한 체계, 도메인 및 포트
https://normal-website.com/example/ 아니오: 다른 체계 및 포트
http://en.normal-website.com/example/ 아니요: 다른 도메인
http://www.normal-website.com/example/ 아니요: 다른 도메인
http://normal-website.com:8080/example/ 아니오: 다른 포트*

 

허용하지 않는 경우 same-origin 이 아니므로 액세스를 거부합니다.

 

따라서 CORS 를 허용하도록 설정이 필요합니다.

 

CORS 요청의 종류

CORS 요청에 따라 설정이 달라지기 때문에 알아야 합니다.

브라우저가 요청 내용을 분석하여 해당하는 방식으로 서버에 요청을 보냅니다.

 

일단, XMLHttpRequest 사용하는 모든 요청은 CORS 요청입니다.

Simple Request, Preflight Request 로 나누어 살펴봅시다.

 

1. Simple Request

CORS Preflight를 발생시키지 않는 요청입니다.

다음의 조건을 모두 만족시켜야 합니다.

 

1. One of the allowed methods

 

- GET

- HEAD

- POST

 

2. Apart fromm the headers automatically set by the user agent

 

- Connection

- User-Agent

- the only headers which are allowed to be manually set are those which the Fetch spec defines as a CORS-safe listed request-header

-- Accept

-- Accept-Language

-- Content-Language

-- Content-type

 

3. The only type/subtype combinations allowed for the media type specified in the Content-Type headers

- application/x-www-form-urlencoded

- multipart/form-data

- text/plain

 

* Safari 의 경우 Accept, Accept-Language, Content-Language 를 nonstandard value 로 취급함. simple request 아님.

 

작동 예시

credentialed requests 의 경우에는 "*" 을 사용할 수 없다고 하니 주의해야겠습니다.

 

2. Preflight Request

- OPTIONS 를 사용해서 선 요청을 보내서 actual request 를 보내도 되는지 확인합니다.

- user data 를 넘겨주어야 하는 경우가 해당되죠!

 first sends an HTTP request using the OPTIONS method
to the resource on the other origin, in order to determine if the actual request is safe to send.
Such cross-origin requests are preflighted since they may have implications for user data.

비교해 볼까요?

simple request

const xhr = new XMLHttpRequest();
const url = 'https://bar.other/resources/public-data/';

xhr.open('GET', url);
xhr.onreadystatechange = someHandler;
xhr.send();

preflight request

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://bar.other/resources/post-here/');
xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
xhr.setRequestHeader('Content-Type', 'application/xml');
xhr.onreadystatechange = handler;
xhr.send('<person><name>Arun</name></person>');
    • a non-standard HTTP X-PINGOTHER request header 
    • uses a Content-Type of application/xml (a custom header)

위의 특징들로 인해, 두 번째 요청은 Preflight 이 되겠네요.

 

작동 예시

Note: As described below, the actual POST request does not include the Access-Control-Request-* headers; they are needed only for the OPTIONS request.

실제 POST 요청에는 Access-Control-Request-* 헤더가 들어있지 않습니다. (그러면?) OPTIONS 요청에만 쓰거든요~ 

 

엥 그러니까 본요청 전에 헤더를 넣어서 보내고, 확인하고 나면 더이상 request 에 넣어보내지 않는단 뜻이군요.

자세한..설명..들어갑니다..(영문과 화이팅)

 

1. preflight 요청 및 응답 

Request

Lines 1 - 10 above represent the preflight request with the OPTIONS method. The browser determines that it needs to send this based on the request parameters that the JavaScript code snippet above was using, so that the server can respond whether it is acceptable to send the request with the actual request parameters. OPTIONS is an HTTP/1.1 method that is used to determine further information from servers, and is a safe method, meaning that it can't be used to change the resource. Note that along with the OPTIONS request, two other request headers are sent (lines 9 and 10 respectively):

 

OPTIONS 메서드로 보낸다.

브라우저가 자바스크립트가 쓰는 request parameter 에 기반하여 보내기로 결정한다.

서버는 진짜 파라미터를 보내도 된다/안된다를 결정한다.

OPTIONS 의 의미 : 서버야, 정보 더 보내도 되겠니?? 나..안전한..메서드야....리소스..못바꾸거든..(받아죠)

 

추가로 Access-Control-Request-Method, Headers 도 보낸다.

 

The Access-Control-Request-Method header notifies the server as part of a preflight request that when the actual request is sent, it will do so with a POST request method. The Access-Control-Request-Headers header notifies the server that when the actual request is sent, it will do so with X-PINGOTHER and Content-Type custom headers. Now the server has an opportunity to determine whether it can accept a request under these conditions.

 

ACR-Method 헤더는 서버에게, 실제 요청이 가면 POST 로 가게될거야 !!! 라고 말한다.

ACR_Headers 헤더는 서버에게, 실제 요청이 가면 X-PINGOTHER, Content-Type Custom header 로 가게될거야!! 라고 한다.

서버는 이것을 보고 음.. 이 조건이면 본 요청을 받아도 되겠군? 하고 결정한다.

 

Response

Lines 13 - 22 above are the response that the server returns, which indicate that the request method (POST) and request headers (X-PINGOTHER) are acceptable. Let's have a closer look at lines 16-19:

 

서버: 음.. POST 메서드 오케이, X-PINGOTHER 헤더 오케이~

 

The server responds with Access-Control-Allow-Origin: https://foo.example, restricting access to the requesting origin domain only. It also responds with Access-Control-Allow-Methods, which says that POST and GET are valid methods to query the resource in question (this header is similar to the Allow response header, but used strictly within the context of access control). The server also sends Access-Control-Allow-Headers with a value of "X-PINGOTHER, Content-Type", confirming that these are permitted headers to be used with the actual request. Like Access-Control-Allow-Methods, Access-Control-Allow-Headers is a comma-separated list of acceptable headers. Finally, Access-Control-Max-Age gives the value in seconds for how long the response to the preflight request can be cached without sending another preflight request. The default value is 5 seconds. In the present case, the max age is 86400 seconds (= 24 hours). Note that each browser has a maximum internal value that takes precedence when the Access-Control-Max-Age exceeds it.

 

Access-Control-Allow-Origin:https://foo.example

서버 : 음, 저 도메인만 request를 보낼 수 있어!

 

Access-Control-Allow-Methods: POST, GET, OPTIONS

서버  : POST, GET 메서드는 유효한 메서드라 앞으로 쿼리 날려도 됨!


Access-Control-Allow-Headers: X-PINGOTHER, Content-Type

서버 : 이 헤더들은 실제 요청할 때 사용해도 됨!


Access-Control-Max-Age: 86400

서버 : 또 다른 preflight request 보내기 전까지 86400 초 동안 캐시됨! 기본은 5초이고 맥시멈 24시간이야.(86400초) 각각의 브라우저는 최대 내부 값을 가지고 있어서 그게 24시간보다 적으면 브라우저것이 적용됨!

 

OPTIONS /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

 

2. preflight 요청 및 응답 

POST /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: https://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: https://foo.example
Pragma: no-cache
Cache-Control: no-cache

<person><name>Arun</name></person>

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain

[Some XML payload]

 

+ 추가 정보

Preflighted requests and redirects

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight. Request requires preflight, which is disallowed to follow cross-origin redirects.

라고 뜨거들랑 참고합시다

Requests with credentials

쿠키 넣어서 보내야 하거들랑 참고합시다

 

HTTP Response Header 알아봅시다. 이제 본격적으로 시작이라고 써있네요.

서버측에서 반환하는 Cross-Origin Resource Sharing specification 이라는 reponse header 에 대해 알아봅시다.

 

Access-Control-Allow-Origin

A returned resource may have one Access-Control-Allow-Origin header with the following syntax:

Access-Control-Allow-Origin: <origin> | *

Access-Control-Allow-Origin specifies either a single origin which tells browsers to allow that origin to access the resource; or else — for requests without credentials — the "*" wildcard tells browsers to allow any origin to access the resource.

 

<> 단 하나의 origin 만이 resource 에 접근할 수 있음을 알려줍니다.

credential 없는 요청의 경우 "*" wildcard 로 어떤 origin 이던 resource 에 접근할 수 있다고 알려줍니다.

 

 

For example, to allow code from the origin https://mozilla.org to access the resource, you can specify:

Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin

If the server specifies a single origin (that may dynamically change based on the requesting origin as part of an allowlist) rather than the "*" wildcard, then the server should also include Origin in the Vary response header to indicate to clients that server responses will differ based on the value of the Origin request header.

 

만약 "*" wildcard 를 사용하지 않고 (a single origin)하나를 지정하고 싶다면, 그게 Origin request header 의 값에 따라 reponse 가 바뀔 수 있다고 클라이언트에게 알려주어야 하므로, Vary에 Origin 을 추가해야만 합니다.

 

Access-Control-Expose-Headers

The Access-Control-Expose-Headers header adds the specified headers to the allowlist that JavaScript (such as getResponseHeader()) in browsers is allowed to access.

 

이 헤더는 특정 헤더를 브라우저의 자바스크립트가 접근할 수 있는 allowlist 에 추가합니다. 

Access-Control-Expose-Headers: <header-name>[, <header-name>]*

For example, the following:

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

…would allow the X-My-Custom-Header and X-Another-Custom-Header headers to be exposed to the browser.

 

Access-Control-Max-Age

The Access-Control-Max-Age header indicates how long the results of a preflight request can be cached. For an example of a preflight request, see the above examples.

이 헤더는 preflight request의 결과가 얼마나 cached 되는지 결정합니다.

Access-Control-Max-Age: <delta-seconds>

The delta-seconds parameter indicates the number of seconds the results can be cached.

 

Access-Control-Allow-Credentials

The Access-Control-Allow-Credentials header indicates whether or not the response to the request can be exposed when the credentials flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note that simple GET requests are not preflighted, and so if a request is made for a resource with credentials, if this header is not returned with the resource, the response is ignored by the browser and not returned to web content.

이 헤더는 credentials flag가 true 일 때, 요청에 대한 응답이 exposed 될지 말지를 결정합니다.

프리플라이트 요청의 응답에 사용이 된다면, 실제 요청이 credential 사용이 가능한지 여부를 판단합니다.

 

simple GET 요청의 경우 프리플라이트가 되지 않기 때문에, credentials 가 포함된 resource 로 request 가 오게 되면, 이 헤더가 resource 와 함께 리턴되지 않기 때문에, response가 브라우저에 의해 무시되고 웹에 뜨지 않게 됩니다.

 

이 헤더를 true 로 설정하면 실제 요청에서 credential 리소스 접근이 가능하다는 것이겠지요.

Access-Control-Allow-Credentials: true

 

Access-Control-Allow-Methods

The Access-Control-Allow-Methods header specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.

 

이 헤더는 resource 에 접근할 때 허용할 methods 를 언급합니다. 

프리플라이트 요청의 응답에 사용됩니다.

Access-Control-Allow-Methods: <method>[, <method>]*

 

 

Access-Control-Allow-Headers

The Access-Control-Allow-Headers header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. This header is the server side response to the browser's Access-Control-Request-Headers header.

 

이 헤더는 실제 요청시에 어떠한 HTTP header 가 사용될 수 있는지 알려줍니다.

프리플라이트 요청의 응답에 사용됩니다.

이 헤더는 브라우저 측의 Access-Contro-Request-Header 에 대응되는 응답 헤더입니다.

Access-Control-Allow-Headers: <header-name>[, <header-name>]*

 

이번엔 클라이언트측 헤더를 볼까요?

The HTTP request headers

This section lists headers that clients may use when issuing HTTP requests in order to make use of the cross-origin sharing feature. Note that these headers are set for you when making invocations to servers. Developers using cross-origin XMLHttpRequest capability do not have to set any cross-origin sharing request headers programmatically.

Origin

The Origin header indicates the origin of the cross-origin access request or preflight request.

Origin: <origin>

The origin is a URL indicating the server from which the request is initiated. It does not include any path information, only the server name.

Note: The origin value can be null.

Note that in any access control request, the Origin header is always sent.

 

Access-Control-Request-Method

The Access-Control-Request-Method is used when issuing a preflight request to let the server know what HTTP method will be used when the actual request is made.

Access-Control-Request-Method: <method>

 

Access-Control-Request-Headers

The Access-Control-Request-Headers header is used when issuing a preflight request to let the server know what HTTP headers will be used when the actual request is made (such as with setRequestHeader()). This browser-side header will be answered by the complementary server-side header of Access-Control-Allow-Headers.

Access-Control-Request-Headers: <field-name>[, <field-name>]*

 

...

정신없이 달려왔습니다.

이제 .. 정말 해결할 수 있겠죠?

...

 

문제 발생

다음과 같은 에러가 발생하였습니다.

 

CORS request 가 블럭되었습니다. request header 가 유효하지 않기 때문입니다.

이를 해결하기 위해서는 CORS request 또는 preflight request 의 response 에 header 가 필요합니다.

저 에러를 보면 Preflight Request 부터 문제가 발생하고 있습니다.

 

어떻게 해결해야 할까요?

 

우선 CORS 작동 과정을 살펴봅시다.

다시 정리하는 기분으로요..


CORS는 어떻게 작동합니까? #

동일 출처 정책은 브라우저에 교차 출처 요청을 차단하도록 지시합니다. 다른 출처에서 공개 리소스를 얻으려면 리소스 제공 서버가 브라우저에 "요청이 들어오는 이 출처가 내 리소스에 액세스할 수 있습니다"라고 알려야 합니다. 브라우저는 이를 기억하고 교차 출처 리소스 공유를 허용합니다.

1단계: 클라이언트(브라우저) 요청 #

브라우저가 교차 출처 요청을 할 때 브라우저는 현재 출처(scheme, host, port)와 함께 Origin 헤더를 추가합니다.

2단계: 서버 응답 #

서버 측에서 서버가 이 헤더를 보고 액세스를 허용하려면 요청한 출처를 지정하는 응답에 Access-Control-Allow-Origin 헤더를 추가해야 합니다(또는 모든 출처를 허용하려면 *).

3단계: 브라우저에서 응답 수신 #

브라우저가 해당 Access-Control-Allow-Origin 헤더와 함께 이 응답을 볼 때 브라우저는 응답 데이터가 클라이언트 사이트와 공유되도록 허용합니다.

 

CORS와 자격 증명 공유 #

개인 정보 보호를 위해 CORS는 일반적으로 요청이 요청자를 식별하지 못하는 "익명 요청"에 사용됩니다. CORS(발신자를 식별할 수 있음)를 사용할 때 쿠키를 보내려면 요청과 응답에 추가 헤더를 덧붙여야 합니다.

요청 #

아래와 같이 가져오기 옵션에 credentials: 'include'를 추가합니다. 여기에는 요청과 함께 쿠키가 포함됩니다.

fetch('https://example.com', {
  mode: 'cors',
  credentials: 'include'
})

응답 #

Access-Control-Allow-Origin은 특정 출처로 설정되어야 하며(*를 사용하는 와일드 카드 없음) Access-Control-Allow-Credentials를 true로 설정해야 합니다.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

 

복잡한 HTTP 호출에 대한 실행 전 요청 #

웹 앱에 복잡한 HTTP 요청이 필요한 경우 브라우저는 요청 체인의 앞에 **실행 전 요청**을 추가합니다.

CORS 사양은 복잡한 요청을 다음과 같이 정의합니다.

  • GET, POST 또는 HEAD 이외의 메서드를 사용하는 요청
  • Accept, Accept-Language 또는 Content-Language 이외의 헤더를 포함하는 요청
  • application/x-www-form-urlencoded, multipart/form-data 또는 text/plain 이외에 Content-Type 헤더가 있는 요청

브라우저는 필요한 경우 실행 전 요청을 생성합니다. 이는 아래와 같은 OPTIONS 요청으로, 실제 요청 메시지보다 먼저 전송됩니다.

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

서버 측에서 애플리케이션은 이 출처에서 애플리케이션이 수락하는 메서드에 대한 정보로 실행 전 요청에 응답해야 합니다.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

서버 응답에는 실행 전 결과를 캐시하는 지속 시간(초)을 지정하기 위한 Access-Control-Max-Age 헤더도 포함될 수 있으므로 클라이언트가 복잡한 요청을 보낼 때마다 실행 전 요청을 할 필요가 없습니다.


다시 에러로 돌아와 봅시다.

 

에러

Access to XMLHttpRequest at 'localhost:8080/users/signup' from origin '
http://localhost:8081/
' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

http protocal scheme을 사용하고 있기 때문에 도움말은 도움이 되지 않네요.

 

해결방법은 다음과 같습니다.

1. CORS 를 발생시키지 않기

2. request 에 헤더를 넣어 (Origin Header) Request 하기

3. 서버에서 모든 출처를 허용하여 Origin Header 여부에 관계없이 Access-Control-Allow-Origin 을 Header에 넣어 Response 하기

 

1.  SOP 준수하기

Frontend 단에서 요청을 https 로 보내면 CORS 가 아니므로 이상이 없겠습니다.

하지만 상황에 따라 CORS 가 필요할 경우가 분명 생길 것입니다. 

따라서 이 방법은 급한 불을 끄는 용도로 사용했습니다.

import axios from "axios"

const API_URL = 'https://localhost:8080/users/'

class AuthService {
    login(user) {
        return axios.post(API_URL + 'api-token-auth/', {
            email: user.email,
            password: user.password
        })
        .then(res => {
            if (res.data.accessToken) {
                localStorage.setItem('user', JSON.stringify(res.data))
            }
            return res.data
        })
    }
    logout (){
        localStorage.removeItem('user')
    }

    register(user) {
        return axios.post(API_URL + "signup", {
            email: user.email,
            nickname: user.nickname,
            password: user.password,
        })
      }
}

export default new AuthService()

 

2. request 에 헤더를 넣어 (Origin Header) Request 보내기

이 방법도 좋지만, 어떤 요청을 받을지 모르기 때문에

서버 단에서 처리하는것이 좋다고 판단하였습니다.

 

3. 서버에서 모든 출처를 허용하여 Origin Header 여부에 관계없이 Access-Control-Allow-Origin 을 Header에 넣어 Response 하기

 

이 방법으로 진행해 보겠습니다.

인터넷을 헤집고 돌아다녔는데 방식이 여러가지이고 상황에 맞는 메서드가 다 달라서

결국 공식문서로 돌아오게 되었습니다. (포기하고 싶은 것이.. 솔찍헌 심정..)

 

List.of 가 작동하지 않는다거나

set으로 할지 add 로 할지 모르겠다거나

특정 상황에서 "*" 이 작동하지 않는다거나...

따라해봐도 작동이 잘 안되더군요..

 

문서 나와

"Cross-Origin 요청을 허용하려면 너가 대놓고 지정해줘야댕!

맞는 CORS configuration 이 없으면 프리플라이트 리퀘스트를 거절할거구 그러면

CORS 헤더가 심플, 실제 요청에 추가되지 않을거니까 브라우저가 리젝하게되거든.

...

각각의 HandlerMapping 은 CorsConfiguration 매핑하고 configured 되지. 

대부분의 경우에 하나의 글로벌 매핑으로 처리되지.

...

HandlerMapping level 의 global CORS configuration 을 handler-level CORS configuration 으로 통합할 수 있어.

예를 들면, @CrossOrigin annotation 을 쓰면 되지.

...

local config와 global config 를 합치는 건 부가적인 사항인데.. 그런 경우에는 하나의 밸류만 허용돼.

그러니까 ..allowCrendentials, maxAge 의 경우에는 local overrides the global!!!  로컬이 적용된다고! 덮어쓰기..! "

 

다시 본론으로 돌아와서...

 

크게 세가지 방법이 있습니다.

 

1. @CrossOrigin

2. GlobalConfiguration

3. CORS Filter

    3-1. Security 미사용시

    3-2. Security 사용시

1. @CrossOrigin

어노테이션 방법입니다. 특정 controller 에 @CrossOrigin 을 지정하여 사용합니다.

 

 

2. Global Configuration

컨트롤러 메서드 레벨을 넘어서 전역 설정이 가능한 방법입니다.

 

 

3-1. CORS Filter

빌트인 필터로 CORS support 를 적용하는 방법입니다.

3-2. Spring Security 사용시

프리플라이트 요청에는 쿠키가 없기 때문에, security에 앞서 CORS 가 수행되어야 not authenticated 에러를 방지할 수 있습니다.

CorsFilter 를 통해 가능하며, ConsConfigurationSource 를 통해 CorsFilter 를 Spring Security와 통합합니다.

 

만약 Spring MVC CORS support (3-1) 을 사용하고 있다면 CorsConfigurationSource 를 구체화할 필요가 없고,

앞선 config를 사용하도록 레버리지 할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

공식문서

https://docs.spring.io/spring-security/reference/servlet/integrations/cors.html#page-title

 

CORS :: Spring Security

Spring Framework provides first class support for CORS. CORS must be processed before Spring Security because the pre-flight request will not contain any cookies (i.e. the JSESSIONID). If the request does not contain any cookies and Spring Security is firs

docs.spring.io

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors-controller

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com

docs.spring.io

https://spring.io/guides/gs/rest-service-cors/

 

Enabling Cross Origin Requests for a RESTful Web Service

this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team

spring.io

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS#preflighted_requests

 

교차 출처 리소스 공유 (CORS) - HTTP | MDN

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라

developer.mozilla.org

 

참고자료

https://www.baeldung.com/spring-security-cors-preflight

https://web.dev/cross-origin-resource-sharing/?utm_source=devtools#preflight-requests-for-complex-http-calls 

 

교차 출처 리소스 공유(CORS)

브라우저의 동일 출처 정책은 다른 출처에서 리소스를 읽는 것을 차단합니다. 이 메커니즘은 악의적인 사이트가 다른 사이트의 데이터를 읽는 것을 방지하지만 합법적인 사용도 방지합니다. 다

web.dev

https://developer.chrome.com/docs/devtools/network/reference/?utm_source=devtools#disable-cache 

 

Network features reference - Chrome Developers

A comprehensive reference of Chrome DevTools Network panel features.

developer.chrome.com

https://developer.chrome.com/docs/devtools/network/reference/?utm_source=devtools#provisional-headers 

 

Network features reference - Chrome Developers

A comprehensive reference of Chrome DevTools Network panel features.

developer.chrome.com

https://toycoms.tistory.com/37

 

Spring Security CORS

CORS란? - HTTP 요청은 기본적으로 Cross-Site HTTP Requests가 가능합니다. Simple 하게 다른 도메인의 Resource를 사용하는것을 말합니다. 하지만 Cross-Site HTTP Requests는 Same Origin Policy를 적용 받기..

toycoms.tistory.com

https://velog.io/@minchae75/Spring-boot-CORS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

[Spring Boot] CORS 적용하기

CORS 관련 에러 해결하기

velog.io