Jak dodać kontrolę dostępu-Allow-Origin w NGINX?


158

Jak ustawić nagłówek Access-Control-Allow-Origin, aby móc używać czcionek internetowych z mojej subdomeny w mojej domenie głównej?


Uwagi:

Przykłady tego i innych nagłówków dla większości serwerów HTTP znajdują się w projektach konfiguracji serwera HTML5BP https://github.com/h5bp/server-configs


4
ah w końcu znalazł lokalizację odpowiedzi / {add_header Access-Control-Allow-Origin "*"; }
Chris McKee,

Odpowiedzi:


182

Nginx należy skompilować za pomocą http://wiki.nginx.org/NginxHttpHeadersModule (domyślnie w Ubuntu i niektórych innych dystrybucjach Linuksa). Możesz to zrobić

location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}

Postępuj zgodnie z tymi instrukcjami, jeśli chcesz wdrożyć to samo rozwiązanie na Apache: stackoverflow.com/questions/11616306/…
camilo_u

6
Ten moduł wydaje się być domyślnie skompilowany (przynajmniej na Ubuntu).
Steve Bennett,

1
także domyślnie skompilowany na Amazon Linux repo
Ross

1
W jakim pliku i lokalizacji powinniśmy umieścić tę dyrektywę lokalizacji?
Sumit Arora

1
To nie działa dla mnie. Nginx 1.10.0, Ubuntu 16.04
Omid Amraei

36

Bardziej aktualna odpowiedź:

#
# Wide-open CORS config for nginx
#
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
}

źródło: https://michielkalkman.com/snippets/nginx-cors-open-configuration.html

Możesz także dodać Access-Control-Expose-Headers(w tym samym formacie, co nagłówki Access-Control-Allow-Headers), aby udostępnić niestandardowe i / lub „nie-proste” nagłówki żądaniom ajax.

Access-Control-Expose-Headers (optional) - The XMLHttpRequest 2 object has a 
getResponseHeader() method that returns the value of a particular response 
header. During a CORS request, the getResponseHeader() method can only access 
simple response headers. Simple response headers are defined as follows:

    Cache-Control
    Content-Language
    Content-Type
    Expires
    Last-Modified
    Pragma
 If you want clients to be able to access other headers, you have to use the
 Access-Control-Expose-Headers header. The value of this header is a comma-
 delimited list of response headers you want to expose to the client.

- http://www.html5rocks.com/en/tutorials/cors/

Konfiguruje dla innych serwerów WWW http://enable-cors.org/server.html


1
W jakiś sposób nie musisz powtarzać tych wierszy dla każdej lokalizacji? Czy możemy umieścić go pod blokiem serwera {}?
geoyws,

@geoyws (bez @ nie dostałem powiadomienia); można to umieścić powyżej lokalizacji, to w porządku :)
Chris McKee

brakuje tutaj kontroli dostępu-odsłonięcia nagłówków
chovy

3
Unikaj używania ifw nginx - nawet oficjalna instrukcja go odradza .
aggregate1166877

1
Chciałbym dodać, że przydatne jest dodanie alwaysopcji do wszystkich add_header, aby nagłówki były dodawane także w przypadku odpowiedzi innych niż 200. Od wersji nginx 1.7.5: nginx.org/en/docs/http/ngx_http_headers_module.html
Mitar

11

Oto artykuł, który napisałem, w którym unika się powielania GET | POST. To powinno sprawić, że zaczniesz używać CORS w Nginx.

Kontrola dostępu nginx zezwala na pochodzenie

Oto przykładowy fragment posta:

server {
  listen        80;
  server_name   api.test.com;


  location / {

    # Simple requests
    if ($request_method ~* "(GET|POST)") {
      add_header "Access-Control-Allow-Origin"  *;
    }

    # Preflighted requests
    if ($request_method = OPTIONS ) {
      add_header "Access-Control-Allow-Origin"  *;
      add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
      add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
      return 200;
    }

    ....
    # Handle request
    ....
  }
}

2
Zgodnie z polityką SF musisz skopiować informacje do posta, a nie tylko link do nich. Strony internetowe mogą zniknąć w dowolnym momencie, co oznaczałoby utratę informacji.
Tim

1
Ważny punkt @ tim, zaktualizowany o kod
gansbrest

Rozważ użycie kodu stanu, 204 No contentponieważ wydaje się to bardziej odpowiednie.
Slava Fomin II

7

Po pierwsze, powiem, że odpowiedź @hellvinz działa dla mnie:

location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}

Jednak postanowiłem odpowiedzieć na to pytanie osobną odpowiedzią, ponieważ udało mi się uruchomić to rozwiązanie po około dziesięciu godzinach szukania rozwiązania.

Wygląda na to, że Nginx domyślnie nie definiuje żadnych (poprawnych) typów czcionek MIME. Postępując zgodnie z tym podręcznikiem , mogłem dodać:

application/x-font-ttf           ttc ttf;
application/x-font-otf           otf;
application/font-woff            woff;
application/font-woff2           woff2;
application/vnd.ms-fontobject    eot;

Do mojego etc/nginx/mime.typespliku Jak już wspomniano, powyższe rozwiązanie działało.


2
Zwykle wskazywałbym ludziom, aby sprawdzili plik typu mime na H5BP github.com/h5bp/server-configs-nginx/blob/master/mime.types :)
Chris McKee

4

Tradycyjna dyrektywa add_header Nginx nie działa z odpowiedziami 4xx. Ponieważ nadal chcemy dodawać do nich niestandardowe nagłówki, musimy zainstalować moduł ngx_headers_more, aby móc korzystać z dyrektywy more_set_headers, która również działa z odpowiedziami 4xx.

sudo apt-get install nginx-extras

Następnie użyj more_set_headers w pliku nginx.conf, wkleiłem poniżej moją próbkę

server {
    listen 80;
    server_name example-site.com;
    root "/home/vagrant/projects/example-site/public";

    index index.html index.htm index.php;

    charset utf-8;

    more_set_headers 'Access-Control-Allow-Origin: $http_origin';
    more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE, HEAD';
    more_set_headers 'Access-Control-Allow-Credentials: true';
    more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept,Authorization';

    location / {
        if ($request_method = 'OPTIONS') {
            more_set_headers 'Access-Control-Allow-Origin: $http_origin';
            more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE, HEAD';
            more_set_headers 'Access-Control-Max-Age: 1728000';
            more_set_headers 'Access-Control-Allow-Credentials: true';
            more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept,Authorization';
            more_set_headers 'Content-Type: text/plain; charset=UTF-8';
            more_set_headers 'Content-Length: 0';
            return 204;
        }
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/example-site.com-error.log error;

    sendfile off;

    client_max_body_size 100m;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    location ~ /\.ht {
        deny all;
    }
}

1

W niektórych przypadkach należy użyć add_headerdyrektyw z, alwaysaby objąć wszystkie kody odpowiedzi HTTP.

location / {
    add_header 'Access-Control-Allow-Origin' '*' always;
}

Z dokumentacji :

Jeśli parametr always jest określony (1.7.5), pole nagłówka zostanie dodane niezależnie od kodu odpowiedzi.

Dodaje określone pole do nagłówka odpowiedzi, pod warunkiem, że kod odpowiedzi wynosi 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13) lub 308 (1.13 .0). Wartość parametru może zawierać zmienne.


0

W moim przypadku, używając Rails 5, jedynym działającym rozwiązaniem było dodanie rack-corsklejnotu. Tak jak:

w / Gemfile

# Gemfile
gem 'rack-cors'

w config / initializers / cors.rb

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:4200'
    resource '*',
      headers: :any,
      methods: %i(get post put patch delete options head)
  end
end

źródło: https://til.hashrocket.com/posts/4d7f12b213-rails-5-api-and-cors


jak to pomaga nginx w obsłudze plików statycznych?
Walf

Używałem nginx jako odwrotnego proxy do obsługi aplikacji Rails 5. Jest to szczególny przypadek, w którym ograniczenie CORS nie pochodziło od nginx, ale od źródłowej aplikacji Rails.
user9869932
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.