Laravel 5 - redirect to HTTPS

Working on my first Laravel 5 project and not sure where and how to place the logic to force HTTPS on my application. The key point here is that there are many domains pointing to the application, and only two out of three use SSL (the third is a backup domain, a long story). So I would like to handle this in my application logic, not in .htaccess.

In Laravel 4.2, I redirected using this code located in filters.php :

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

I think Middleware is where it should be implemented, but I can't figure it out using it.

Thank!

UPDATE

If you use Cloudflare, like me, this is achieved by adding a new page rule in the control panel.

+91
php laravel laravel-5 laravel-routing
Feb 09 '15 at 4:14
source share
18 answers

You can make it work with the Middleware class. Let me give you an idea.

 namespace MyApp\Http\Middleware; use Closure; use Illuminate\Support\Facades\App; class HttpsProtocol { public function handle($request, Closure $next) { if (!$request->secure() && App::environment() === 'production') { return redirect()->secure($request->getRequestUri()); } return $next($request); } } 

Then apply this middleware to each request by adding the rule setting to the Kernel.php file, for example:

 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' ]; 

In the above example, the middleware redirects each request to https if:

  1. The current request does not contain a secure protocol (http)
  2. If your environment is production . Therefore, simply adjust the settings to your preference.

Cloudflare

I use this code in a production environment using WildCard SSL, and the code works correctly. If I remove && App::environment() === 'production' and test it in localhost, the redirect will also work. Thus, the presence or absence of established SSL is not a problem. It looks like you need to pay very close attention to the Cloudflare layer in order to redirect it to the Https protocol.

Edit 03/23/2015

Thanks to the @Adam Link suggestion: this is probably caused by the headers that Cloudflare skips. CloudFlare probably hits your server via HTTP and sends an X-Forwarded-Proto header, which announces that it is forwarding an HTTPS request. You need to add another line to your middleware that says ...

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

... trust CloudFlare headers. This will stop the redirect loop.

Edit 09/27/2016 - Laravel v5.3

Just add the middleware class to the web group in 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 ], ]; 

Remember that the web group is applied to each route by default, so you do not need to explicitly set the web in routes or controllers.

Edit 08/23/2018 - Laravel v5.7

  • To redirect the request depending on the environment, you can use App::environment() === 'production' . For the previous version, there was env('APP_ENV') === 'production' .
  • Using \URL::forceScheme('https'); not actually redirected. It just builds links with https:// after rendering the website.
+200
Feb 09 '15 at 6:22
source

Another option that worked for me in AppServiceProvider is to put this code in the load method:

 \URL::forceScheme('https'); 

The function written before forceScheme ('https') was incorrect; its forceScheme

+49
02 Oct. '16 at 14:10
source

Alternatively, if you use Apache, you can use the .htaccess file to use your URLs to use the https prefix. In Laravel 5.4, I added the following lines to my .htaccess file, and it worked for me.

 RewriteEngine On RewriteCond %{HTTPS} !on RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 
+23
Apr 26 '17 at 12:00
source

for laravel 5.4 use this format to get https redirection instead of .htaccess

 namespace App\Providers; use Illuminate\Support\Facades\URL; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot() { URL::forceScheme('https'); } } 
+13
Apr 28 '17 at 9:50
source

As in manix, but in one place. Medium Push HTTPS Software

 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); } } 
+10
Jun 14 '16 at 17:00
source

This is for Larave 5.2.x and higher. If you want to be able to serve some content over HTTPS and another over HTTP, here is a solution that worked for me. You may wonder why someone wants to serve only some content via HTTPS? Why not serve everything over HTTPS?

Although serving the entire site via HTTPS is quite normal, interrupting everything over HTTPS has additional costs on your server. Remember that encryption is not cheap. Slight overhead also affects the response time of your application. You can argue that the hardware is cheap and the impact is negligible, but I digress :) I do not like the idea of ​​showing on large pages with images, etc. Via https. So there you go. This is similar to what others offer above using middleware, but it is a complete solution that allows you to switch between HTTP / HTTPS.

Create middleware first.

 php artisan make:middleware ForceSSL 

Here's what your middleware should look like.

 <?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); } } 

Please note that I do not filter based on the environment, because I have HTTPS settings for both the local developer and production, so there is no need.

Add the following to your routeMiddleware \ App \ Http \ Kernel.php so that you can choose which route group should use 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, ]; 

Next, I would like to provide two main groups of login / registration, etc. And everything else is behind Auth middleware.

 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 }); 

Make sure your middleware is correctly applied to your routes from the console.

 php artisan route:list 

You have now protected all forms or confidential areas of your application. The key now is to use the view template to define secure and public (non-https) links.

Based on the above example, you would make your protected links as follows:

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

Unprotected links can be represented as

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

This makes the full url such as https: // yourhost / login and http: // yourhost / aboutus

If you have not provided a fully qualified URL with http and use the relative URL of the link ('/ aboutus'), then https will be saved after the user visits the protected site.

Hope this helps!

+6
Aug 27 '16 at 14:45
source

How about using a .htaccess file to redirect https? This should be placed in the root of the project (not in the shared folder). Your server must be configured to point to the project root directory.

 <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> 

I use this for laravel 5.4 (the latest version for writing this answer), but it should continue to work for function versions, even if laravel modifies or removes some functions.

+5
Mar 18 '17 at 4:06 on
source

You can use RewriteRule to force ssl in the same .htaccess folder with your index.php
Please add how to attach the image, add it before all the rules are different setting ssl .htaccess

+5
Jun. 01 '18 at 4:47
source

in IndexController.php put

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

in the AppServiceProvider.php application

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

}

In AppServiceProvider.php, each redirect will go to the https URL and for the HTTP request that we need, as soon as the redirection is therefore in IndexController.php We just need to do the redirection once

+3
Feb 02 '17 at 18:29
source

The answers above did not help me, but it seems that Denise Turan rewrote .htaccess in a way that works with the Heroku download platform: https://www.jcore.com/2017/01/29/force-https-on-heroku-using -htaccess /

 RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 
+3
Dec 13 '17 at 14:50
source

Here's how to do it on Heroku

To force SSL on your speakers, but not locally, add at the end of your .htaccess to public /:

 # Force https on heroku... # Important fact: X-forwarded-Proto will exist at your heroku dyno but wont locally. # Hence we want: "if x-forwarded exists && if its not https, then rewrite it": RewriteCond %{HTTP:X-Forwarded-Proto} . RewriteCond %{HTTP:X-Forwarded-Proto} !https RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 

You can check this on your local machine with:

 curl -H"X-Forwarded-Proto: http" http://your-local-sitename-here 

This sets the X-forwarded heading to the form that it will take on the hero.

those. he imitates as heroku dictates, he sees a request.

You will receive a response on your local computer:

 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="https://tm3.localhost:8080/">here</a>.</p> </body></html> 

This is a redirect. This is what the hero is about to return to the client if you install .htaccess as described above. But this does not happen on your local machine, because X-forwarded will not be installed (we faked it with the curl above to see what happens).

+1
Feb 20 '18 at 17:32
source

For Laravel 5.6, I had to change the state a bit to make it work.

from:

 if (!$request->secure() && env('APP_ENV') === 'prod') { return redirect()->secure($request->getRequestUri()); } 

In order to:

 if (empty($_SERVER['HTTPS']) && env('APP_ENV') === 'prod') { return redirect()->secure($request->getRequestUri()); } 
+1
Apr 29 '18 at 11:08
source

It worked for me. I created my own PHP code to redirect it to https. Just include this code in header.php

 <?php if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { $protocol = 'https://'; } else { $protocol = 'http://'; } $notssl = 'http://'; if($protocol==$notssl){ $url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";?> <script> window.location.href ='<?php echo $url?>'; </script> <?php } ?> 
+1
Jul 03 '18 at 19:04
source

If you use CloudFlare, you can simply create a page rule to always use HTTPS: Force SSL Cloudflare This redirects each http: // request to https: //

In addition to this, you should also add something like this to the \ app \ Providers \ AppServiceProvider.php boot () function:

 if (env('APP_ENV') === 'production' || env('APP_ENV') === 'dev') { \URL::forceScheme('https'); } 

This ensures that every link / path in your application uses https: // instead of http: //.

+1
Jul 05 '18 at 21:24
source

I am adding this alternative as I suffer a lot from this problem. I tried everything differently and nothing worked. So, I came up with a workaround for this. It may not be the best solution, but it really works -

FYI, I am using Laravel 5.6

 if (App::environment('production')) { URL::forceScheme('https'); } 

production <- It should be replaced by the value of APP_ENV in your .ENV file

+1
Jul 21 '18 at 11:10
source

I use the following middleware in Laravel 5.6.28:

 namespace App\Http\Middleware; use App\Models\Unit; use Closure; use Illuminate\Http\Request; class HttpsProtocol { public function handle($request, Closure $next) { $request->setTrustedProxies([$request->getClientIp()], Request::HEADER_X_FORWARDED_ALL); if (!$request->secure() && env('APP_ENV') === 'prod') { return redirect()->secure($request->getRequestUri()); } return $next($request); } } 
+1
Jul 30 '18 at 15:35
source

A slightly different approach tested in Laravel 5.7

 <?php namespace App\Http\Middleware; use Closure; class ForceHttps { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $app_url = env('APP_URL'); if ( !$request->secure() && substr($app_url, 0, 8) === 'https://' ) { return redirect()->secure($request->getRequestUri()); } return $next($request); } } 
+1
Nov 14 '18 at 9:13
source

The easiest way is at the application level. In file

 app/Providers/AppServiceProvider.php 

add the following:

 use Illuminate\Support\Facades\URL; 

and in the boot () method add the following:

 $this->app['request']->server->set('HTTPS', true); URL::forceScheme('https'); 

This should redirect the entire request to https at the application level.

(Note: this has been tested with Laravel 5.5 LTS)

0
Oct 18 '18 at 13:45
source



All Articles