headers에 자신의 키를 추가하여 요청 보내기

5879 단어 CORSnginxVue.jsaxios

0. 환경



nginx:1.18.0
vue.js:2.6.12

1. 개요



ALB + ec2 (nginx + gunicorn + flask)의 구성으로 배포하고 ALB에서 요청 헤더를 확인하고 액세스 제한을 적용하는 것이 목표였습니다. UI 측은 cloudfront + s3 으로 배포가 끝났으며 여기에서 서버로 요청을 보냅니다.
요청을 보낼 때 cors 오류가 발생하여 해결에 시간이 걸렸으므로 비망록으로 작성합니다.
  • 발생한 오류
  • Access to XMLHttpRequest at 'http://xxx.xxx.elb.amazonaws.com/yyy' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    2. 결론



    nginx의 설정 (conf 파일)에 Preflight Request에 대한 설정을 기술한다.
    location / {
          # preflightに対するレスポンス指定
          if ($request_method = 'OPTIONS') {
              add_header Access-Control-Allow-Origin '*'; # corsの許可
              add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE'; # メソッドの許可
              add_header Access-Control-Allow-Headers 'Origin, Authorization, Accept, Content-Type, key'; # ここにヘッダーに追加するキーを追加する!
              add_header Access-Control-Max-Age 3600;
          ...
    

    3. 각종 설정·코드 확인



    3.1 ALB 설정



    ALB는 헤더에 key=value가 포함되어 있으면 ec2로 전달할 설정입니다.


    3.2 UI (vue.js) 측의 요청 코드



    헤더에 key를 추가하고 axios에서 ALB에 GET 요청을 보냅니다.

    vue.js
    let config = {
      headers: {
        'key': 'value'
      },
    };
    this.axios
      .get('http://xxx.xxx.elb.amazonaws.com/hello', config)
      .then((response) => {
        console.log(response)
    ...
    

    4. 빠진 점·해결 방법



    ① CORS의 요청은 Simple RequestPreflight Request의 2종류로 나눌 수 있다. Preflight Request 의 경우, 서버측에서 허가하는 설정이 필요
    ② 요청 헤더에 독자적인 헤더를 추가하는 경우(이번 경우라면 key )는 서버측에서 그것을 허가하는 설정이 필요

    ① 해결



    이에 대해서는 이 사이트가 매우 참고가 되었습니다.
    CORS (Cross-Origin Resource Sharing)에 대해 정리해 보았습니다.

    아래의 모든 조건에 해당하는 경우 브라우저는 preflight 요청을 보낼 필요가 없다고 판단하고 간단한 요청을 보냅니다. 그렇지 않으면 preflight 요청을 제출합니다.

    · HTTP 메소드가 GET, POST, HEAD 중 하나
    · HTTP 헤더에 Accept, Accept-Language, Content-Language, Content-Type 이외의 필드가 포함되지 않음
    · Content-Type의 값은 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나

    이 경우에는 요청 헤더에 key가 들어 있기 때문에 Preflight Request로 간주됩니다. Preflight Request 의 응답에는, 액세스 허가하는 메소드를 리스폰스 헤더에 포함할 필요가 있는 것 같습니다 (결론의 코드 Access-Control-Allow-Methods 의 부분).

    ②의 해결



    메소드를 허용한 것처럼 헤더 권한도 필요합니다.
    이 사이트 에는 다음과 같은 설명이 있습니다.

    CORS 세이프리스트 요청 헤더, Accept, Accept-Language, Content-Language, Content-Type은 항상 허용되며 이 헤더에 열거할 필요가 없습니다.

    위의 헤더를 제외하고는 기본적으로 허용되지 않는 것 같습니다. 이 경우에는 key 를 허용하고 싶으므로 추가합니다 (결론 코드 Access-Control-Allow-Headers 부분).

    5. 감상



    CORS에 대해 잘 이해하지 못했기 때문에 해결에 상당한 시간을 보냈습니다.
    잘못된 점, 보충 등 있으면 코멘트를 받고 싶습니다!

    참고



    CORS 정리
    어쨌든 CORS를 아는 ...는 이미 끝난다.
    CORS (Cross-Origin Resource Sharing)에 대해 정리해 보았습니다.
    MDN web docs
    (감사합니다..)

    좋은 웹페이지 즐겨찾기