Как включить CORS на веб-сервере Apache (включая предварительную проверку и настраиваемые заголовки)?

Общий:

Request URL:x/site.php
Request Method:OPTIONS
Status Code:302 Found
Remote Address:x.x.x.x:80

Заголовки ответа:

view source
Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Origin:*
Access-Control-Max-Age:300
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Length:0
Content-Type:text/html; charset=UTF-8
Date:Thu, 02 Mar 2017 14:27:21 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Location:y
Pragma:no-cache
Server:Apache/2.4.25 (Ubuntu)

Заголовки запроса:

view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:x
Origin:http://127.0.0.1:3000
Pragma:no-cache
Referer:http://127.0.0.1:3000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.90 Safari/537.36

Конфигурация виртуального хоста Apache выглядит так:

    <IfModule mod_headers.c>
           Header set Access-Control-Allow-Origin "http://127.0.0.1:3000"
           Header set Access-Control-Allow-Origin "http://127.0.0.1"
           Header set Access-Control-Max-Age "300"
           Header set Access-Control-Allow-Credentials "true"
           Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
           Header set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, PATCH, OPTIONS"
    </IfModule>

Предварительный запрос пропускает конфигурацию apache и напрямую попадает в мое веб-приложение, которое выполняет перенаправление (отсюда 302 и местоположение: y).

Я не знаю, почему предполетный запрос не обрабатывается apache?


person basickarl    schedule 02.03.2017    source источник


Ответы (1)


Чтобы полностью включить CORS для веб-сервера Apache, вам необходимо настроить его так:

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Authorization"
Header always set Access-Control-Allow-Methods "GET"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
Header always set Access-Control-Max-Age "600"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

Более подробное объяснение на https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-response-headers-allowing-everything-through/

Некоторые общие замечания о том, какие значения следует установить для различных Access-Control- заголовков ответов:


Итак, в отношении конкретного запроса, указанного в вопросе, необходимо внести следующие конкретные изменения и дополнения:

  • Используйте Header always set вместо Header set

  • Используйте mod_rewrite для обработки OPTIONS, просто отправив обратно 200 OK с этими заголовками

  • Запрос имеет Access-Control-Request-Headers:authorization, поэтому в конфигурации Apache добавьте Authorization в заголовок ответа Access-Control-Allow-Headers.

  • Origin - это «запрещенное» имя заголовка, установленное браузером, а Accept - имя заголовка из списка безопасных CORS, поэтому вам не нужно включать их в Access-Control-Allow-Headers

  • Запрос не отправляет Content-Type, поэтому он не нужен в Access-Control-Allow-Headers в ответе (и никогда не требуется для GET запросов, а в противном случае необходим только в том случае, если тип отличается от application/x-www-form-urlencoded, text/plain или multipart/form-data)

  • Для Access-Control-Allow-Methods запрос выглядит просто GET, поэтому, если вы не планируете также делать _36 _ / _ 37 _ / _ 38 _ / _ 39_ запросов, нет смысла явно включать их

person sideshowbarker    schedule 02.03.2017
comment
Спасибо за это! Первый из многих сообщений, которые работали / имели смысл для меня. - person Jon Vote; 27.02.2019
comment
Наличие Header always set Access-Control-Allow-Origin "*", похоже, лишает смысла CORS. - person Chris Stryczynski; 23.11.2020
comment
@ChrisStryczynski См. Ответ на странице stackoverflow.com/a/43154277/441757. Я знаю, что есть некоторые руководства / источники, которые утверждают или подразумевают, что цель CORS - заблокировать доступ других сайтов к вашему контенту. Но на самом деле суть CORS вовсе не в этом - вместо этого цель CORS заключается в предотвращении атак с повышением привилегий. См., Например, ответ на странице stackoverflow.com/a/29167709/441757. А если ваш сайт не использует / не требует учетных данных для доступа, тогда нет атаки на повышение привилегий, которую можно было бы предотвратить - Access-Control-Allow-Origin: * использовать безопасно. - person sideshowbarker; 23.11.2020
comment
@ChrisStryczynski CORS на самом деле не предназначен для блокировки любого доступа к вашему контенту с других сайтов, и на самом деле CORS вовсе не является эффективным способом заблокировать любой доступ к вашему контенту с других сайтов, потому что ваш контент все еще доступен из бэкэнд-кода на стороне сервера. Поэтому для любого, кто действительно хочет заблокировать доступ, установка какого-либо механизма аутентификации - правильный способ сделать это, потому что это также заблокирует доступ и из серверного кода на стороне сервера. - person sideshowbarker; 23.11.2020
comment
Однако ни в вопросе, ни в ответе этот подстановочный знак не указан - поэтому в идеале следует упомянуть это предостережение. - person Chris Stryczynski; 23.11.2020