Весь сайт должен обслуживаться через https. У меня есть "https" в каждом маршруте. Однако, как мне перенаправить их на https, если они попытаются выполнить его через http?
Route::group(array('https'), function()
{
// all of our routes
}
Весь сайт должен обслуживаться через https. У меня есть "https" в каждом маршруте. Однако, как мне перенаправить их на https, если они попытаются выполнить его через http?
Route::group(array('https'), function()
{
// all of our routes
}
Использование приложения:: before
Возможно, вы сможете использовать блок App::before()
в файле app/filters.php
.
Измените блок, чтобы включить простую проверку, чтобы проверить, защищен ли текущий запрос, а если нет, перенаправьте его.
App::before(function($request)
{
if( ! Request::secure())
{
return Redirect::secure(Request::path());
}
});
Использование фильтров
Другим вариантом может быть создание такого фильтра. Люди обычно хранят это также в app/filters.php
.
Route::filter('force.ssl', function()
{
if( ! Request::secure())
{
return Redirect::secure(Request::path());
}
});
Затем вы можете применить этот новый фильтр к любому из ваших маршрутов, групп маршрутов или контроллеров, подобных этому.
Индивидуальный маршрут
Route::get('something', ['before' => 'force.ssl'], function()
{
return "This will be forced SSL";
});
Группа маршрутов
Route::group(['before' => 'force.ssl'], function()
{
// Routes here.
});
контроллер
Вам нужно будет сделать это в вашем методе управления __construct()
.
public function __construct()
{
$this->beforeFilter('force.ssl');
}
Еще один ответ может заключаться в том, чтобы ваш веб-сервер справился с этим. Если вы используете Apache, вы можете использовать функцию RedirectSSL, чтобы убедиться, что все запросы идут на HTTPS-версию вашего сайта, и если не перенаправить их. Это произойдет до того, как Laravel даже получит запрос.
Если вы находитесь в NGINX, вы можете выполнить это, имея два блока сервера. Один для обычного HTTPS на порту 80, а другой для HTTPS на порту 443. Затем настройте обычный серверный блок, чтобы всегда перенаправлять на версию ssl.
server {
listen 80;
server_name mydomain.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name mydomain.com;
ssl on;
# other server config stuff here.
}
Я бы лично пошел с этим вариантом, поскольку сам PHP не должен ничего перерабатывать. Как правило, дешевле обрабатывать такую проверку на уровне веб-сервера.
Для пользователей, использующих Laravel 4/5 и Elastic Beanstalk, принудительное HTTPS сложно использовать эти методы, потому что isSecure()
вернет false
. Кроме того, использование перенаправления .htaccess
приведет к циклу переадресации для Chrome и задержкам загрузки страниц в Firefox.
Эта настройка предназначена для
aws
на компьютере под управлением Windows. Linux может немного отличаться?После нескольких часов моих попыток мне удалось получить все HTTP-запросы, перенаправленные на HTTPS, с помощью следующих шагов:
Получить сертификат SSL. Гиды и провайдеры многочисленны и могут быть найдены с помощью поиска Google.
Загрузите сертификат в AWS, используя команду консоли aws
. Структура команды:
aws iam upload-server-certificate --server-certificate-name CERTIFICATE_NAME --certificate-body "file://PATH_TO_CERTIFICATE.crt" --private-key "file://YOUR_PRIVATE_KEY.pem" --certificate-chain "file://YOUR_CERTIFICATE_CHAIN.ca-bundle" --path /cloudfront/
Создайте приложение эластичного бобового стежка. Продолжайте процесс настройки. После того, как приложение настроено, перейдите в Конфигурация → Уровень сети → Балансировка нагрузки и нажмите значок шестеренки.
Выберите Безопасный порт прослушивателя как 443. Выберите Протокол как HTTPS. Выберите CERTIFICATE_NAME
от шаг 2 для идентификатора сертификата SSL. Сохраните конфигурацию.
Перейдите в консоль . Нажмите Экземпляры EC2. Нажмите Балансировщики нагрузки. Нажмите балансировку нагрузки. Нажмите Экземпляры и прокрутите вниз, чтобы просмотреть экземпляры EC2, назначенные этому балансировщику нагрузки. Если экземпляр EC2 имеет то же имя, что и ваш URL-адрес приложения (или что-то близкое), обратите внимание на DNS Name для балансировки нагрузки. Он должен быть в формате awseb-e-...
Вернитесь в консоль . Нажмите CloudFront. Нажмите Создать рассылку. Выберите дистрибутив Веб.
Настройте дистрибутив. Задайте свое Имя домена происхождения в DNS-имя балансира нагрузки, которое вы нашли в шаге 5 . Установите Протокол протокола просмотра на Перенаправить HTTP на HTTPS. Установите строки прямого запроса на Да. Установите Альтернативные имена доменов (CNAME) на URL-адреса, которые вы хотите использовать для своего приложения. Установите сертификат SSL на CERTIFICATE_NAME
, который вы загрузили в шаг 2. Создайте свой дистрибутив.
Нажмите на имя своего дистрибутива в CloudFront. Нажмите Происхождение, выберите источник и нажмите Изменить. Убедитесь, что Протокольная политика происхождения < соответствует. Возвращаться. Нажмите Поведение, выберите источник и нажмите Изменить. Измените Переслать заголовки на белый список и добавьте Хост. Сохранить.
Перейдите в консоль . Нажмите Маршрут 53. Нажмите Хостинговые зоны. Нажмите Создать хостинговую зону. Настройте свое доменное имя. После настройки нажмите Создать набор записей. Введите свою запись A. Выберите Псевдоним как Да. Ваш Alias Target - ваш дистрибутив CloudFront. Сохраните запись.
Настройте свои серверы имен для своего домена, чтобы указать на серверы маршрутизации 53. Подождите, пока все будет распространено, что может быть несколько часов. Перейдите к своему URL. Вы будете автоматически перенаправлены на HTTPS.
"Но подождите, мои ссылки не идут на HTTPS!?" Вам нужно обработать заголовок X-Forwarded-Proto
, который пройдет CloudFront. Для Laravel 4, следуйте этому руководству. Для Laravel 5 запустите это:
php artisan make:middleware EB_SSL_Trust
И затем добавьте это в файл EB_SSL_Trust
:
public function handle($request, Closure $next)
{
$request->setTrustedProxies( [ $request->getClientIp() ] );
return $next($request);
}
И добавьте это в свой App\Http\Kernel.php
файл:
protected $middleware = [
...
'App\Http\Middleware\EB_SSL_Trust',
...
];
Примечание. Все ваши активы, такие как CSS, JS или изображения, должны быть отправлены через HTTPS. Если вы используете Laravel для создания этих ссылок, используйте secure_asset()
для создания URL-адреса HTTPS в вашем представлении.
Использование .htaccess Apache для laravel 4.2.X
Исходный файл
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Редактировать файл /public/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Использование фильтров устарело в Laravel 5.1. *. Это идеальная работа для MiddleWare.
Создайте промежуточное ПО и в разделе дескриптора поставьте
public function handle($request, Closure $next)
{
if(! $request->secure()) {
return redirect()->secure($request->path());
}
return $next($request);
}
Затем просто зарегистрируйте свое промежуточное программное обеспечение в своем Kernel.php и используйте его с помощью ваших маршрутов или контроллеров.
Объединение предыдущих ответов и обновление для Laravel 4.2:
Route::filter('secure', function () {
if (! Request::secure()) {
return Redirect::secure(
Request::path(),
in_array(Request::getMethod(), ['POST', 'PUT', 'DELETE']) ? 307 : 302
);
}
});
Route::when('*', 'secure');
Если вы хотите перенаправить на тот же URL-адрес, но используя https, вы должны использовать Request::getRequestUri()
вместо Request::path()
:
App::before(function($request)
{
if( ! Request::secure())
{
return Redirect::secure(Request::getRequestUri());
}
});
Если у вас есть проблема, когда по какой-то причине Request::secure()
возвращает false, даже если url https
, это может быть потому, что значение $_SERVER ['HTTPS] не существует.
Это обходное решение:
App::before(function ($request){
// Force https
if(!Request::secure() && array_get($_SERVER, 'SERVER_PORT') != 443){
return Redirect::secure(Request::path());
}
});
У меня возникла проблема с форсированием ssl при выполнении запроса POST. Он всегда будет перенаправляться на GET. Это происходит, потому что Redirect::secure()
по умолчанию использует перенаправление 302.
Чтобы ваш запрос POST был перенаправлен правильно, используйте что-то вроде
return Redirect::secure("your/path/here", 307)
Это приведет к тому, что ваш запрос будет сохранять исходный метод запроса после перенаправления.
Я не очень разбираюсь в HTTP и HTTPS, поэтому мне жаль, если этот ответ не очень хорош.
Я понимаю, что существует проблема, что даже когда клиент и (клиент) сервер используют HTTPS, Request::secure()
может возвращать false, потому что ваше приложение может работать на другом сервере, который, возможно, не получает запрос https.
Я размещаю свое приложение laravel в героике, и похоже, что это так. Мой guess заключается в том, что основной (указанный клиентом) сервер является балансировщиком нагрузки и когда запрос пересылается, он поступает на другой сервер как обычный HTTP-запрос.
Если такая пересылка может произойти, вам не следует просто проверять, чтобы Request::secure()
был true
. Мне было поручено (кем-то в #laravel @irc.freenode.com) также проверить Request::server('HTTP_X_FORWARDED_PROTO')
, чтобы убедиться, что он равен 'https'
.
Итак, если вы намерены следовать другому совету здесь и выполнить перенаправление в случае небезопасного, попробуйте также проверить этот параметр сервера.
Для laravel 5.1 вы должны использовать заданный код в App\Http\Providers\[email protected]
$router->filter('force.ssl', function () {
if ( ! request()->secure() ) {
return redirect()->secure(request()->path());
}
});
Теперь вы можете использовать это в файле маршрутов.
Route::group(['before' => 'force.ssl'], function () {
// Routes here
});
вы также можете добавить ['before' => 'force.ssl']
в $router->group()
в
App\Http\Providers\[email protected]
Если за прокси и Request:: secure() не работает.
App::before( function( $request )
{
// set the current IP (REMOTE_ADDR) as a trusted proxy
Request::setTrustedProxies( [ $request->getClientIp() ] );
});
Объединяя предыдущие ответы, чтобы использовать константы и методы, доступные в Laravel 4.2.
routes.php
Route::when('*', 'secure');
filters.php
use Illuminate\Http\Response as IlluminateResponse;
Route::filter('secure', function ()
{
if ( ! Request::secure() && Request::getPort() != 443)
{
return Redirect::secure(
Request::path(),
in_array(Request::getMethod(), ['POST', 'PUT', 'DELETE'])
? IlluminateResponse::HTTP_TEMPORARY_REDIRECT
: IlluminateResponse::HTTP_FOUND
);
}
});
Если вам нужно самому использовать Laravel 4 для обработки перенаправления (например, я), я бы пошел на следующую настройку (объяснение как комментарии в коде):
Фильтр маршрута:
// app/filters.php
Route::filter('ssl.force', function()
{
if(App::environment('production') && !Request::secure())
{
// don't set a session cookie when redirecting to another scheme to
// avoid dropping the session when switching scheme
Config::set('session.driver', 'array');
// preserve query string while redirecting by using fullUrl()
// instead of Redirect::secure + Request::path()
$url = str_replace('http://', 'https://', Request::fullUrl());
return Redirect::to($url, 302, array(), true);
}
// secure cookies for https
Config::set('session.secure', Request::secure());
});
Затем примените фильтр как фильтр до вашего маршрута или группы маршрутов. например:
// app/routes.php
Route::group(array('before' => 'ssl.force'), function () {
// SSL routes
});
Это сработало для меня в Apache 2.4
Я изменил .htaccess в корневой папке Laravel
С
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Для
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Вот альтернативное решение для Laravel 5.2.x или выше.