Nginx에서 조건부 헤더를 갖는 것이 불가능합니까?

Nginx에서 조건부 헤더를 갖는 것이 불가능합니까?

현재 Nginx를 사용하여 조건부로 CORS 헤더 세트만 반환하려고 합니다. 처음에는 다음과 같은 작업 구성이 이미 있었기 때문에 간단한 작업처럼 보였습니다.

upstream api-app {
  server unix:/tmp/api-app.sock fail_timeout=0;
}

server {
  listen 80;
  # [other server stuff...]

  # CORS headers added to all ALL responses of this server (needed for all requests)
  more_set_headers 'Access-Control-Allow-Methods: GET,POST,PATCH,PUT,DELETE,OPTIONS';
  more_set_headers 'Access-Control-Allow-Origin: *';
  more_set_headers 'Access-Control-Allow-Credentials: true';
  more_set_headers 'Access-Control-Request-Method: GET,POST,PATCH,PUT,DELETE,OPTIONS';
  more_set_headers 'Access-Control-Request-Headers: Content-Type';
  more_set_headers 'Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept,Session-Id,Role-Id,Visitor-Id,X-Window-Location';
  more_set_headers 'Access-Control-Expose-Headers: X-Total-Entries,X-Total-Pages,X-Page,X-Per-Page,X-Folder-Hierarchy';

  location / {
    # For OPTIONS request only return above headers and no content (also allow caching them)
    if ($request_method = 'OPTIONS') {
      # cache above (Access-Control) headers
      add_header 'Access-Control-Max-Age' 600;

      # set content length and type just for good measure:
      add_header 'Content-Length' 0;
      add_header 'Content-Type' 'text/plain charset=UTF-8';

      # return 204 - no content
      return 204;
    }

    # Forward requests to actual app (if all above conditions did not match)
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_read_timeout 35;
    proxy_send_timeout 35;

    proxy_pass http://api-app;
  }
}

그래서 CORS 헤더 섹션을 s.th로 변경하고 싶었습니다. 이와 같이

# ...
  set $cors '';

  if ($http_origin ~ '^https?://(some.domain|some.other.domain|other-allows.domain)') {
      set $cors 'true';
  }

  if ($cors = 'true') {
      more_set_headers 'Access-Control-Allow-Methods: GET,POST,PATCH,PUT,DELETE,OPTIONS';
      more_set_headers 'Access-Control-Allow-Origin: $http_origin';
      more_set_headers 'Access-Control-Allow-Credentials: true';
      more_set_headers 'Access-Control-Request-Method: GET,POST,PATCH,PUT,DELETE,OPTIONS';
      more_set_headers 'Access-Control-Request-Headers: Content-Type';
      more_set_headers 'Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept,Session-Id,Role-Id,Visitor-Id,X-Window-Location';
      more_set_headers 'Access-Control-Expose-Headers: X-Total-Entries,X-Total-Pages,X-Page,X-Per-Page,X-Folder-Hierarchy';
  }
  

  location / {
# ...

그러나 if 문에서는 사용할 수 없다고 nginx -t빨리 말했습니다 . more_set_headersadd_header도 마찬가지입니다.

나는 그 부분에서 그것이 효과가 있을 것이라고 생각했다 location. 하지만 나는 이것이 우리 모두가 알고 있듯이 좋은 해결책이 아니라는 것을 이미 알고 있었습니다.nginx 위치 섹션에서 악한 경우. 그리고 OPTIONS 요청에 대해 CORS 헤더가 손실되므로 내 말이 옳았습니다. 이미 if 사례가 있었습니다(반환 시 OK 사례).

또한 Nginxs를 사용하는 옵션도 발견했습니다.지도 기능. 하지만 이는 전체 헤더 블록을 추가하려는 경우가 아니라 헤더 값을 변경하려는 경우에만 작동합니다.

그래서 내 질문은 다음과 같습니다. 조건부로(지도를 사용하지 않고) 위치 블록 외부에 헤더를 추가하는 방법이 있습니까? 이상적으로는 CORS 섹션을 포함하여 여러 서버(예: nginx 사이트)에서 사용할 수 있습니다.

답변1

more_set_headers빈 문자열을 허용 하는지 모르겠습니다 . 승인되면 여러 map명령문을 정의할 수 있습니다.

map $http_origin $cors_methods {
    default "";
    ~^https?://(some.domain|some.other.domain|other-allows.domain) Access-Control-Allow-Methods: GET,POST,PATCH,PUT,DELETE,OPTIONS;
}

map $http_origin $cors_origin {
    default "";
    ~^https?://(some.domain|some.other.domain|other-allows.domain) Access-Control-Allow-Origin: $http_origin;
}

그런 다음 다음을 사용하십시오.

more_set_headers $cors_methods;
more_set_headers $cors_origin;

관련 정보