Điểm:3

Có thể có các tiêu đề có điều kiện trong Nginx không?

lá cờ cn

Tôi hiện đang cố gắng chỉ trả về một bộ tiêu đề CORS có điều kiện bằng Nginx. Lúc đầu, nó có vẻ như là một nhiệm vụ đơn giản, vì tôi đã có cấu hình hoạt động này:

ứng dụng api ngược dòng {
  máy chủ unix:/tmp/api-app.sock fail_timeout=0;
}

người phục vụ {
  nghe 80;
  # [nội dung máy chủ khác...]

  # Tiêu đề CORS được thêm vào tất cả TẤT CẢ các phản hồi của máy chủ này (cần thiết cho tất cả các yêu cầu)
  more_set_headers 'Phương thức kiểm soát truy cập-cho phép: GET,POST,PATCH,PUT,DELETE,OPTIONS';
  more_set_headers 'Kiểm soát truy cập-Cho phép-Xuất xứ: *';
  more_set_headers 'Kiểm soát truy cập-Cho phép-Thông tin xác thực: true';
  more_set_headers 'Phương thức kiểm soát truy cập-yêu cầu: GET,POST,PATCH,PUT,DELETE,OPTIONS';
  more_set_headers 'Kiểm soát truy cập-Yêu cầu-Tiêu đề: Loại nội dung';
  more_set_headers 'Kiểm soát truy cập-Cho phép-Tiêu đề: Nguồn gốc,X-Được yêu cầu-Với,Loại nội dung,Chấp nhận,Id phiên,Id vai trò,Id khách truy cập,Vị trí cửa sổ X';
  more_set_headers 'Kiểm soát truy cập-Hiển thị tiêu đề: X-Tổng mục nhập,X-Tổng số trang,X-Trang,X-Per-Page,X-Phân cấp thư mục';

  địa điểm / {
    # Đối với yêu cầu TÙY CHỌN chỉ trả về các tiêu đề ở trên và không có nội dung (cũng cho phép lưu chúng vào bộ đệm)
    nếu ($request_method = 'TÙY CHỌN') {
      # bộ đệm ở trên (Kiểm soát truy cập) tiêu đề
      add_header 'Kiểm soát truy cập-Tuổi tối đa' 600;

      # đặt độ dài nội dung và loại chỉ để đo lường tốt:
      add_header 'Độ dài nội dung' 0;
      add_header 'Loại nội dung' 'văn bản/bộ ký tự đơn giản=UTF-8';

      # return 204 - không có nội dung
      trả lại 204;
    }

    # Chuyển tiếp yêu cầu tới ứng dụng thực tế (nếu tất cả các điều kiện trên không khớp)
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
    proxy_set_header Máy chủ $http_host;
    proxy_redirect tắt;
    proxy_read_timeout 35;
    proxy_send_timeout 35;

    proxy_pass http://api-app;
  }
}

Vì vậy, tôi chỉ muốn thay đổi phần tiêu đề CORS thành s.th. như thế này

#...
  đặt $cors '';

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

  nếu ($cors = 'true') {
      more_set_headers 'Phương thức kiểm soát truy cập-cho phép: GET,POST,PATCH,PUT,DELETE,OPTIONS';
      more_set_headers 'Kiểm soát truy cập-Cho phép-Xuất xứ: $http_origin';
      more_set_headers 'Kiểm soát truy cập-Cho phép-Thông tin xác thực: true';
      more_set_headers 'Phương thức kiểm soát truy cập-yêu cầu: GET,POST,PATCH,PUT,DELETE,OPTIONS';
      more_set_headers 'Kiểm soát truy cập-Yêu cầu-Tiêu đề: Loại nội dung';
      more_set_headers 'Kiểm soát truy cập-Cho phép-Tiêu đề: Nguồn gốc,X-Được yêu cầu-Với,Loại nội dung,Chấp nhận,Id phiên,Id vai trò,Id khách truy cập,Vị trí cửa sổ X';
      more_set_headers 'Kiểm soát truy cập-Hiển thị tiêu đề: X-Tổng mục nhập,X-Tổng số trang,X-Trang,X-Per-Page,X-Phân cấp thư mục';
  }
  

  địa điểm / {
#...

Tuy nhiên nginx -t nhanh chóng nói với tôi more_set_headers không thể được sử dụng trong một câu lệnh if. add_header cũng không được.

tôi nhận ra rằng trong địa điểm nó sẽ hoạt động. Nhưng tôi đã biết đây sẽ không phải là giải pháp tốt như tất cả chúng ta đều biết nếu là ác trong phần vị trí nginx. Và tôi đã đúng khi đó các tiêu đề CORS sẽ bị mất đối với yêu cầu TÙY CHỌN, tôi đã có một trường hợp if cho (một trường hợp OK, khi nó trả về).

Tôi cũng bắt gặp tùy chọn sử dụng Nginxs chức năng bản đồ. Nhưng điều đó chỉ hoạt động nếu tôi muốn thay đổi giá trị tiêu đề, không phải nếu tôi muốn thêm toàn bộ khối tiêu đề.

Vì vậy, câu hỏi của tôi là như sau: Có cách nào để thêm tiêu đề một cách có điều kiện (không sử dụng bản đồ) và bên ngoài khối vị trí không? Lý tưởng nhất là cho phép bao gồm phần CORS để tôi có thể sử dụng nó trong nhiều máy chủ (tức là các trang web nginx).

lá cờ cn
Để hoàn thiện, tôi đã tìm ra một cách khó khăn để thực hiện công việc này bằng cách sao chép phần CORS vào phần vị trí (nếu được phép) và một lần nữa vào điều kiện OTPIONS để trả lại các tiêu đề CORS trong trường hợp đó, nhưng tôi không muốn để sử dụng cái này trong sản xuất :P
Điểm:3
lá cờ us

tôi không biết nếu more_set_headers chấp nhận chuỗi rỗng. Nếu nó chấp nhận, thì bạn có thể xác định nhiều bản đồ các câu lệnh:

bản đồ $http_origin $cors_methods {
    mặc định "";
    ~^https?://(some.domain|some.other.domain|other-allows.domain) Phương thức-Kiểm soát-Cho phép-Truy cập: GET,POST,PATCH,PUT,DELETE,OPTIONS;
}

bản đồ $http_origin $cors_origin {
    mặc định "";
    ~^https?://(some.domain|some.other.domain|other-allows.domain) Access-Control-Allow-Origin: $http_origin;
}

Và sau đó sử dụng cái này:

more_set_headers $cors_methods;
more_set_headers $cors_origin;
lá cờ cn
Vâng, đó là những gì tôi cố gắng đề cập với chức năng bản đồ. Tuy nhiên, tôi hy vọng có một cách dễ dàng hơn để bật/tắt tất cả các tiêu đề cùng một lúc, nhưng có lẽ không có tiêu đề nào.
lá cờ cn
Ngoài ra, tôi nhận ra rằng chức năng bản đồ không thể được sử dụng trong khối máy chủ, chỉ trong khối http.
lá cờ us
Có, `map` phải được xác định ở cấp độ `http`, nhưng điều đó không ảnh hưởng đến tính hữu dụng của nó.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.