Laravel 5 – перенаправление на HTTPS

Работа над моим первым проектом Laravel 5 и не уверен, где и как разместить логику, чтобы заставить HTTPS на моем приложении. Ключевым моментом здесь является то, что существует много доменов, указывающих на приложение, и только два из трех используют SSL (третий – резервный домен, длинный рассказ). Поэтому я бы хотел обработать это в логике моего приложения, а не в .htaccess.

В Laravel 4.2 я выполнил перенаправление с помощью этого кода, расположенного в filters.php :

 App::before(function($request) { if( ! Request::secure()) { return Redirect::secure(Request::path()); } }); 

Я думаю, что Middleware – это нечто вроде этого, но я не могу это понять.

Благодаря!

ОБНОВИТЬ

Если вы используете Cloudflare, как я, это достигается добавлением нового правила страницы на панели управления.

Вы можете заставить его работать с классом Middleware. Позвольте мне дать вам представление.

 namespace MyApp\Http\Middleware; use Closure; class HttpsProtocol { public function handle($request, Closure $next) { if (!$request->secure() && env('APP_ENV') === 'prod') { return redirect()->secure($request->getRequestUri()); } return $next($request); } } 

Затем примените это промежуточное ПО к каждому запросу, добавив настройку правила в файл Kernel.php , например:

 protected $middleware = [ 'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode', 'Illuminate\Cookie\Middleware\EncryptCookies', 'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse', 'Illuminate\Session\Middleware\StartSession', 'Illuminate\View\Middleware\ShareErrorsFromSession', // appending custom middleware 'MyApp\Http\Middleware\HttpsProtocol' ]; 

В приведенном выше примере промежуточное ПО перенаправляет каждый запрос на https, если:

  1. Текущий запрос не содержит защищенного протокола (http)
  2. Если ваша среда равна prod . Поэтому просто настройте параметры в соответствии с вашими предпочтениями.

Cloudflare

Я использую этот код в рабочей среде с помощью WildCard SSL, и код работает правильно. Если я && env('APP_ENV') === 'prod' и тестирую его в localhost, перенаправление также работает. Таким образом, наличие или отсутствие установленного SSL не является проблемой. Похоже, вам нужно уделять очень пристальное внимание слою Cloudflare, чтобы перенаправить его на протокол Https.

Изменить 23/03/2015

Благодаря предложению @Adam Link : это, скорее всего, вызвано заголовками, которые пропускает Cloudflare. CloudFlare, вероятно, попадает на ваш сервер через HTTP и передает заголовок X-Forwarded-Proto, который объявляет, что он пересылает запрос HTTPS. Вам нужно добавить еще одну строку в свое промежуточное ПО, которое говорит …

 $request->setTrustedProxies( [ $request->getClientIp() ] ); 

… доверять заголовкам CloudFlare. Это остановит цикл перенаправления

Редактировать 27/09/2016 – Laravel v5.3

Просто добавьте класс промежуточного программного обеспечения в web группу в kernel.php file :

 protected $middlewareGroups = [ 'web' => [ \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, // here \MyApp\Http\Middleware\HttpsProtocol::class ], ]; 

Помните, что web группа применяется к каждому маршруту по умолчанию, поэтому вам не нужно явно устанавливать web в маршрутах или контроллерах.

Другой вариант, который работал для меня, в AppServiceProvider поместил этот код в метод загрузки:

 \URL::forceScheme('https'); 

Функция, написанная до forceSchema ('https'), была неправильной, ее forceScheme

для laravel 5.4 используйте этот формат, чтобы получить перенаправление https вместо .htaccess

 namespace App\Providers; use Illuminate\Support\Facades\URL; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot() { URL::forceScheme('https'); } } 

Как и ответ Маниса, но в одном месте. Среднее ПО для принудительной HTTPS

 namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class ForceHttps { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if (!app()->environment('local')) { // for Proxies Request::setTrustedProxies([$request->getClientIp()]); if (!$request->isSecure()) { return redirect()->secure($request->getRequestUri()); } } return $next($request); } } 

В качестве альтернативы, если вы используете Apache, вы можете использовать файл .htaccess для принудительного использования ваших URL-адресов для использования https . На Laravel 5.4 я добавил следующие строки в файл .htaccess и это сработало для меня.

 RewriteEngine On RewriteCond %{HTTPS} !on RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 

Это для Larave 5.2.x и выше. Если вы хотите иметь возможность обслуживать некоторый контент через HTTPS, а другие через HTTP – это решение, которое сработало для меня. Вы можете удивиться, почему кто-то хочет обслуживать только некоторый контент через HTTPS? Почему бы не обслуживать все по HTTPS?

Хотя, вполне нормально обслуживать весь сайт через HTTPS, разделение всего по HTTPS имеет дополнительные накладные расходы на вашем сервере. Помните, что шифрование не дешево. Небольшие накладные расходы также влияют на время ответа вашего приложения. Вы можете утверждать, что товарное оборудование дешево, а влияние незначительно, но я отвлекаюсь 🙂 Мне не нравится идея подачи маркетингового контента на большие страницы с изображениями и т. Д. По https. Итак, вот оно. Это похоже на то, что другие предлагают выше, используя промежуточное программное обеспечение, но это полное решение, которое позволяет вам переключаться между HTTP / HTTPS.

Сначала создайте промежуточное ПО.

 php artisan make:middleware ForceSSL 

Это то, на что должно выглядеть ваше промежуточное ПО.

 <?php namespace App\Http\Middleware; use Closure; class ForceSSL { public function handle($request, Closure $next) { if (!$request->secure()) { return redirect()->secure($request->getRequestUri()); } return $next($request); } } 

Обратите внимание, что я не фильтрую на основе среды, потому что у меня есть настройка HTTPS для локального разработчика и производства, поэтому нет необходимости.

Добавьте следующее на свой маршрутMiddleware \ App \ Http \ Kernel.php, чтобы вы могли выбрать, какая группа маршрутов должна принудительно использовать SSL.

  protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'forceSSL' => \App\Http\Middleware\ForceSSL::class, ]; 

Затем я хотел бы защитить две базовые группы login / signup и т. Д. И все остальное за промежуточным ПО Auth.

 Route::group(array('middleware' => 'forceSSL'), function() { /*user auth*/ Route::get('login', 'AuthController@showLogin'); Route::post('login', 'AuthController@doLogin'); // Password reset routes... Route::get('password/reset/{token}', 'Auth\PasswordController@getReset'); Route::post('password/reset', 'Auth\PasswordController@postReset'); //other routes like signup etc }); Route::group(['middleware' => ['auth','forceSSL']], function() { Route::get('dashboard', function(){ return view('app.dashboard'); }); Route::get('logout', 'AuthController@doLogout'); //other routes for your application }); 

Убедитесь, что ваши посредники применяются к вашим маршрутам должным образом с консоли.

 php artisan route:list 

Теперь вы создали все формы или уязвимые области приложения, теперь ключевым моментом является использование вашего шаблона представления для определения ваших безопасных и общедоступных (не https) ссылок.

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

 <a href="{{secure_url('/login')}}">Login</a> <a href="{{secure_url('/signup')}}">SignUp</a> 

Незащищенные ссылки могут отображаться как

 <a href="{{url('/aboutus',[],false)}}">About US</a></li> <a href="{{url('/promotion',[],false)}}">Get the deal now!</a></li> 

Это означает, что вы получаете полный URL-адрес, например https: // yourhost / login и http: // yourhost / aboutus

Если вы не предоставили полный URL с http и использовали относительный URL-адрес ссылки ('/ aboutus'), то https будет сохраняться после того, как пользователь посещает безопасный сайт.

Надеюсь это поможет!

в IndexController.php put

 public function getIndex(Request $request) { if ($request->server('HTTP_X_FORWARDED_PROTO') == 'http') { return redirect('/'); } return view('index'); } 

в приложении AppServiceProvider.php

 public function boot() { \URL::forceSchema('https'); 

}

В AppServiceProvider.php каждый переадресация будет идти по URL-адресу https и для HTTP-запроса, который нам нужен, как только перенаправление, так и в IndexController.php. Нужно только раз перенаправить

Как насчет использования файла .htaccess для достижения переадресации https? Это должно быть помещено в корень проекта (не в общую папку). Ваш сервер должен быть настроен для указания в корневой каталог проекта.

 <IfModule mod_rewrite.c> RewriteEngine On # Force SSL RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # Remove public folder form URL RewriteRule ^(.*)$ public/$1 [L] </IfModule> 

Я использую это для laravel 5.4 (последняя версия для написания этого ответа), но он должен продолжать работать для версий функций, даже если laravel изменяет или удаляет некоторые функции.

Ответы выше не помогли мне, но оказалось, что Дениз Туран переписал .htaccess таким образом, который работает с балансировщиком Heroku: https://www.jcore.com/2017/01/29/force-https -он-Heroku-помощь-Htaccess /

 RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]