У меня есть приложение, созданное с помощью Laravel 5, действующего как API. В моем файле .htaccess есть следующее: перенаправление всех маршрутов на https:
RewriteEngine On # Force SSL RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Это прекрасно работает для следующего:
https://example.com/route
но бросает MethodNotAllowedHttpException, если я пытаюсь получить к нему доступ с http. Он правильно перенаправляет на https, но, похоже, неправильно выполняет запрос POST, так как все мои маршруты разрешают только POST.
Есть ли способ исправить это, не изменяя мои маршруты, чтобы позволить GET?
Чтобы заставить https, ваш RewriteRule необходим для принудительного внешнего перенаправления. В случае вашего правила вы принудительно перенаправляете 301 ( R=301
). Большинство браузеров и клиентов предназначены для автоматического перехода к переадресации, но они (неправильно) делают это с помощью запроса GET.
Таким образом, когда клиент отправляет запрос POST с данными на http://example.com/route
, ваш сервер отвечает перенаправлением 301 на https://example.com/route
, а затем клиент делает запрос GET без данных на новый URL. Как вы можете видеть, вы не можете просто изменить свои маршруты, чтобы принимать запросы GET, потому что данные, отправленные в исходном запросе POST, будут удалены.
Одним из вариантов было бы добавить условие перезаписи, чтобы не перенаправлять запросы POST:
# Force SSL RewriteCond %{HTTPS} !=on RewriteCond %{REQUEST_METHOD} !=POST RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Тем не менее, это в значительной степени побеждает цель того, что вы пытаетесь выполнить. Вся эта концепция заключается в том, чтобы заставить https повсюду. Было бы глупо применять его везде, кроме случаев, когда вы отправляете данные в свое приложение.
Другой возможный вариант – изменить 301 перенаправление на перенаправление 307. Несмотря на то, что клиенты не должны изменять метод запроса для перенаправления 301/302, большинство клиентов делают это из-за двусмысленности в спецификациях и существующих функциях. Из-за этого 307 были добавлены с конкретной идеей, что если этот код состояния используется, метод запроса НЕ ДОЛЖЕН быть изменен. Однако 307 классифицируется как «временное перенаправление», поэтому он не будет кэшироваться и может повлиять на ваш SEO. Кроме того, этот статус был добавлен в спецификацию HTTP / 1.1, поэтому вы можете столкнуться с некоторыми клиентами, которые не знают, как обрабатывать 307.
Ваш лучший вариант, вероятно, просто для отказа от незащищенных POST-запросов. Или перенаправляйте их на страницу с ошибкой, объясняя, что вы не принимаете незащищенные запросы POST.
RewriteEngine On # Forbid non-secure POSTs RewriteCond %{HTTPS} !=on RewriteCond %{REQUEST_METHOD} =POST RewriteRule ^ / [F,L] # Force SSL RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]