jQuery에서는 CORS 오류를 이해하지만 Postman에서는 그렇지 않음

jQuery에서는 CORS 오류를 이해하지만 Postman에서는 그렇지 않음
JavaScript

브라우저에서 CORS 오류가 발생하는 이유는 무엇입니까?

JavaScript를 사용하여 RESTful API에 연결할 때 "요청된 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다." 오류가 발생할 수 있습니다. 이 오류는 일반적으로 웹 페이지가 웹 페이지를 제공한 도메인이 아닌 다른 도메인에 요청하는 것을 제한하는 브라우저의 동일 출처 정책으로 인해 발생합니다.

흥미롭게도 Postman과 같은 도구를 통해 동일한 요청을 하면 이러한 오류가 발생하지 않습니다. 이러한 차이는 개발자에게 당혹스러울 수 있습니다. XMLHttpRequest 또는 가져오기 호출이 브라우저의 CORS에 의해 차단되지만 Postman에서는 차단되지 않는 이유를 이해하는 것은 보안 웹 애플리케이션 문제를 해결하고 개발하는 데 중요합니다.

Flask 백엔드로 JavaScript의 CORS 문제 해결

jQuery를 사용한 JavaScript 프론트엔드 코드

// JavaScript (jQuery) frontend script
$(document).ready(function() {
  $("#loginButton").click(function() {
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: 'http://localhost:5000/login',
      data: JSON.stringify({
        username: 'user',
        password: 'pass'
      }),
      contentType: 'application/json',
      crossDomain: true,
      xhrFields: {
        withCredentials: true
      }
    }).done(function(data) {
      console.log('Login successful');
    }).fail(function(xhr, textStatus, errorThrown) {
      alert('Error: ' + xhr.responseText);
    });
  });
});

플라스크에서 CORS 설정

Flask를 사용하는 Python 백엔드 코드

# Python (Flask) backend script
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app, supports_credentials=True)

@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if username == 'user' and password == 'pass':
        return jsonify({'message': 'Login successful'}), 200
    else:
        return jsonify({'message': 'Invalid credentials'}), 401

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Flask 백엔드로 JavaScript의 CORS 문제 해결

jQuery를 사용한 JavaScript 프런트엔드 코드

// JavaScript (jQuery) frontend script
$(document).ready(function() {
  $("#loginButton").click(function() {
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: 'http://localhost:5000/login',
      data: JSON.stringify({
        username: 'user',
        password: 'pass'
      }),
      contentType: 'application/json',
      crossDomain: true,
      xhrFields: {
        withCredentials: true
      }
    }).done(function(data) {
      console.log('Login successful');
    }).fail(function(xhr, textStatus, errorThrown) {
      alert('Error: ' + xhr.responseText);
    });
  });
});

플라스크에서 CORS 설정

Flask를 사용하는 Python 백엔드 코드

# Python (Flask) backend script
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app, supports_credentials=True)

@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if username == 'user' and password == 'pass':
        return jsonify({'message': 'Login successful'}), 200
    else:
        return jsonify({'message': 'Invalid credentials'}), 401

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

CORS 문제가 Postman이 아닌 브라우저에서 발생하는 이유

CORS(Cross-Origin Resource Sharing)에 대해 이해해야 할 중요한 측면 중 하나는 브라우저가 사용자를 보호하기 위해 구현하는 보안 메커니즘입니다. 브라우저는 웹 페이지가 웹 페이지를 제공한 도메인이 아닌 다른 도메인에 요청하는 것을 방지하는 동일 출처 정책을 시행합니다. 이는 악성 웹사이트가 JavaScript를 통해 다른 웹사이트의 민감한 정보에 접근하는 것을 방지하기 위한 보안 조치입니다. XMLHttpRequest를 만들거나 브라우저에서 요청을 가져오면 'Access-Control-Allow-Origin' 서버의 응답에 헤더가 있습니다. 이 헤더가 없거나 요청 원본을 허용하지 않으면 브라우저가 요청을 차단하여 CORS 오류가 발생합니다.

반면 Postman은 브라우저가 아니라 API 테스트를 위한 도구입니다. 브라우저 환경 내에서 실행되지 않기 때문에 Same-Origin Policy를 시행하지 않습니다. 따라서 동일한 보안 검사를 수행하지 않으며 제한 없이 모든 도메인에 대한 요청을 허용합니다. 이것이 Postman을 사용하여 동일한 요청을 할 때 CORS 문제가 발생하지 않는 이유입니다. 개발자가 CORS 관련 문제를 효과적으로 해결하려면 이러한 차이점을 이해하는 것이 중요합니다. 적절한 CORS 헤더를 포함하도록 서버를 구성하면 웹 애플리케이션이 외부 API와 오류 없이 안전하게 통신할 수 있도록 보장할 수 있습니다.

CORS 및 JavaScript에 대한 일반적인 질문과 답변

  1. CORS란 무엇입니까?
  2. CORS는 웹 페이지의 제한된 리소스를 리소스가 시작된 도메인 외부의 다른 도메인에서 요청할 수 있도록 허용하는 메커니즘인 Cross-Origin Resource Sharing의 약자입니다.
  3. 브라우저가 동일 출처 정책을 시행하는 이유는 무엇입니까?
  4. 동일 출처 정책은 사용자의 데이터를 보호하고 악의적인 웹사이트가 JavaScript를 통해 다른 도메인의 민감한 정보에 액세스하는 것을 방지하기 위해 시행됩니다.
  5. Postman이 CORS를 시행하지 않는 이유는 무엇입니까?
  6. Postman은 브라우저가 아니고 브라우저 환경에서 실행되지 않기 때문에 CORS를 적용하지 않으므로 동일 출처 정책을 준수할 필요가 없습니다.
  7. 웹 애플리케이션에서 CORS 오류를 어떻게 해결할 수 있나요?
  8. CORS 오류를 해결하려면 적절한 항목을 포함하도록 서버를 구성하십시오. 'Access-Control-Allow-Origin' 응답 헤더에 요청 원본을 허용합니다.
  9. 무엇을 하는가? 'Access-Control-Allow-Origin' 헤더는 해?
  10. 그만큼 'Access-Control-Allow-Origin' 헤더는 리소스에 액세스할 수 있는 원본을 지정하여 원본 간 요청을 활성화합니다.
  11. 목적은 무엇입니까? withCredentials XMLHttpRequest에서?
  12. 그만큼 withCredentials 속성은 쿠키나 인증 헤더와 같은 자격 증명을 사용하여 사이트 간 액세스 제어 요청을 해야 하는지 여부를 나타냅니다.
  13. 내 서버에 다음이 포함되어 있는데도 CORS 오류가 발생하는 이유는 무엇입니까? 'Access-Control-Allow-Origin' 머리글?
  14. 다음과 같은 다른 필수 CORS 헤더가 있는 경우에도 CORS 오류가 발생할 수 있습니다. 'Access-Control-Allow-Methods' 또는 'Access-Control-Allow-Headers'이 없거나 잘못 구성되었습니다.
  15. 내 브라우저에서 CORS를 비활성화할 수 있나요?
  16. 브라우저에서 CORS를 비활성화하면 보안이 손상되므로 권장되지 않습니다. 대신 CORS를 적절하게 처리하도록 서버를 구성하세요.
  17. CORS의 실행 전 요청이란 무엇입니까?
  18. 실행 전 요청은 실제 요청을 보내도 안전한지 확인하기 위해 OPTIONS 메서드를 사용하여 브라우저에서 수행한 초기 요청입니다. 서버에서 필수 CORS 헤더를 확인합니다.

토론 마무리

CORS와 동일 출처 정책의 미묘한 차이를 이해하는 것은 웹 개발자에게 필수적입니다. 브라우저는 사용자를 보호하기 위해 엄격한 보안 조치를 시행하지만 Postman과 같은 도구는 이러한 제한을 우회하여 API 테스트를 더 쉽게 만듭니다. 필요한 CORS 헤더로 백엔드를 적절하게 구성함으로써 개발자는 프런트엔드와 백엔드 간의 원활하고 안전한 통신을 보장할 수 있습니다. CORS 문제를 해결하는 것은 기능적이고 사용자 친화적인 웹 애플리케이션을 만드는 데 중요합니다.