it-swarm.com.de

Laravel 5 - Weiterleitung zu HTTPS

Ich arbeite an meinem ersten Laravel 5 Projekt und bin mir nicht sicher, wo oder wie ich die Logik platzieren soll, um HTTPS auf meiner App zu erzwingen Drei verwenden SSL (die dritte ist eine Fallback-Domain, eine lange Geschichte). Daher möchte ich dies eher in der Logik meiner App als in .htaccess behandeln.

In Laravel 4.2 habe ich die Weiterleitung mit diesem Code durchgeführt, der sich in filters.php Befindet:

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

Ich denke, Middleware ist der Ort, an dem so etwas implementiert werden sollte, aber ich kann es nicht ganz herausfinden, wenn ich es benutze.

Vielen Dank!

UPDATE

Wenn Sie Cloudflare wie ich verwenden, wird dies durch Hinzufügen einer neuen Seitenregel in Ihrem Steuerungsfeld erreicht.

96
NightMICU

Sie können dafür sorgen, dass es mit einer Middleware-Klasse funktioniert. Lass mich dir eine Idee geben.

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

Wenden Sie diese Middleware dann auf jede Anforderung an, indem Sie die Regel wie folgt in die Datei Kernel.php Einfügen:

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'       

];

Im obigen Beispiel leitet die Middleware jede Anfrage an https weiter, wenn:

  1. Die aktuelle Anfrage enthält kein sicheres Protokoll (http)
  2. Wenn Ihre Umgebung gleich production ist. Passen Sie die Einstellungen einfach Ihren Wünschen an.

Wolkenfackel

Ich verwende diesen Code in einer Produktionsumgebung mit einer WildCard SSL und der Code funktioniert korrekt. Wenn ich && App::environment() === 'production' entferne und in localhost teste, funktioniert die Umleitung ebenfalls. Ein installiertes SSL zu haben oder nicht, ist also nicht das Problem. Sieht so aus, als müssten Sie Ihre Cloudflare-Ebene sehr genau beobachten, um zum HTTP-Protokoll umgeleitet zu werden.

Bearbeiten 23/03/2015

Dank des Vorschlags von @Adam Link: Es liegt wahrscheinlich an den Headern, die Cloudflare übergibt. CloudFlare trifft Ihren Server wahrscheinlich über HTTP und übergibt einen X-Forwarded-Proto-Header, der angibt, dass eine HTTPS-Anforderung weitergeleitet wird. Sie müssen eine weitere Zeile in Ihre Middleware einfügen, die besagt ...

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

... um den Headern zu vertrauen, die CloudFlare sendet. Dies stoppt die Umleitungsschleife

Edit 27/09/2016 - Laravel v5.3

Müssen Sie nur die Middleware-Klasse in web Gruppe 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

    ],
];

Denken Sie daran, dass die Gruppe web standardmäßig auf jede Route angewendet wird, sodass Sie web nicht explizit in Routen oder Controllern festlegen müssen.

Edit 23/08/2018 - Laravel v5.7

  • Um eine Anfrage abhängig von der Umgebung umzuleiten, können Sie App::environment() === 'production' verwenden. Für die vorherige Version war env('APP_ENV') === 'production'.
  • Die Verwendung von \URL::forceScheme('https'); leitet nicht weiter. Es werden nur Links mit https:// Erstellt, sobald die Website gerendert wurde.
211
manix

Eine andere Option, die für mich funktioniert hat, in AppServiceProvider diesen Code in die Boot-Methode einfügen:

\URL::forceScheme('https');

Die vor forceScheme ('https') geschriebene Funktion war falsch, ihr forceScheme

49
Constantin Stan

Wenn Sie Apache verwenden, können Sie alternativ die Datei .htaccess Verwenden, um zu erzwingen, dass Ihre URLs das Präfix https verwenden. In Laravel 5.4 habe ich die folgenden Zeilen zu meiner .htaccess - Datei hinzugefügt und es hat bei mir funktioniert.

RewriteEngine On

RewriteCond %{HTTPS} !on
RewriteRule ^.*$ https://%{HTTP_Host}%{REQUEST_URI} [L,R=301]
26
Assad Ullah Ch

verwenden Sie für laravel 5.4 dieses Format, um eine https-Umleitung anstelle von .htaccess zu erhalten

namespace App\Providers;

use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        URL::forceScheme('https');
    }
}
15
Arun Yokesh

Ähnlich wie die Antwort von Manix, aber an einem Ort. Middleware, um HTTPS zu erzwingen

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

Dies gilt für Larave 5.2.x und höher. Wenn Sie die Option haben möchten, einige Inhalte über HTTPS und andere über HTTP bereitzustellen, ist dies eine Lösung, die für mich funktioniert hat. Sie fragen sich vielleicht, warum jemand nur einige Inhalte über HTTPS bereitstellen möchte? Warum nicht alles über HTTPS bereitstellen?

Obwohl es völlig in Ordnung ist, die gesamte Site über HTTPS zu bedienen, hat das Trennen aller Daten über HTTPS einen zusätzlichen Aufwand auf Ihrem Server. Denken Sie daran, Verschlüsselung ist nicht billig. Der geringe Overhead wirkt sich auch auf die Reaktionszeit Ihrer App aus. Man könnte argumentieren, dass Standardhardware billig und die Auswirkungen vernachlässigbar sind, aber ich schweife ab :) Mir gefällt die Idee nicht, große Seiten mit Bildern usw. über https zu vermarkten. Also geht es los. Es ähnelt dem, was andere oben unter Verwendung von Middleware vorgeschlagen haben, aber es ist eine vollständige Lösung, mit der Sie zwischen HTTP/HTTPS hin und her wechseln können.

Erstellen Sie zunächst eine Middleware.

php artisan make:middleware ForceSSL

So sollte Ihre Middleware aussehen.

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

Beachten Sie, dass ich nicht nach der Umgebung filtere, da ich HTTPS sowohl für die lokale Entwicklung als auch für die Produktion eingerichtet habe, sodass dies nicht erforderlich ist.

Fügen Sie Ihrer routeMiddleware\App\Http\Kernel.php Folgendes hinzu, damit Sie auswählen können, welche Routengruppe SSL erzwingen soll.

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

Als nächstes möchte ich zwei grundlegende Gruppen Login/Signup usw. und alles andere hinter Auth Middleware sichern.

Route::group(array('middleware' => 'forceSSL'), function() {
/*user auth*/
Route::get('login', '[email protected]');
Route::post('login', '[email protected]');

// Password reset routes...
Route::get('password/reset/{token}', 'Auth\[email protected]');
Route::post('password/reset', 'Auth\[email protected]');

//other routes like signup etc

});


Route::group(['middleware' => ['auth','forceSSL']], function()
 {
Route::get('dashboard', function(){
    return view('app.dashboard');
});
Route::get('logout', '[email protected]');

//other routes for your application
});

Vergewissern Sie sich, dass Ihre Middlewares von der Konsole aus ordnungsgemäß auf Ihre Routen angewendet wurden.

php artisan route:list

Nachdem Sie alle Formulare oder vertraulichen Bereiche Ihrer Anwendung gesichert haben, müssen Sie mithilfe Ihrer Ansichtsvorlage Ihre sicheren und öffentlichen (nicht https-) Links definieren.

Anhand des obigen Beispiels würden Sie Ihre sicheren Links wie folgt rendern:

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

Nicht sichere Links können als gerendert werden

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

Dadurch wird eine vollständig qualifizierte URL wie https: // yourhost/login und http: // yourhost/aboutus gerendert

Wenn Sie keine vollqualifizierte URL mit http rendern und eine relative Link-URL ('/ aboutus') verwenden, bleibt https bestehen, nachdem ein Benutzer eine sichere Site besucht hat.

Hoffe das hilft!

6
na-98

Wie wäre es einfach mit der Datei . Htaccess, um eine https-Umleitung zu erreichen? Dies sollte im Projektstamm abgelegt werden (nicht im öffentlichen Ordner). Ihr Server muss so konfiguriert sein, dass er auf das Projektstammverzeichnis verweist.

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

Ich verwende dies für laravel 5.4 (neueste Version zum Zeitpunkt des Schreibens dieser Antwort), aber es sollte weiterhin für Feature-Versionen funktionieren, auch wenn laravel einige Funktionen ändern oder entfernen .

5
Maulik Gangani

Sie können RewriteRule verwenden, um ssl in demselben Ordner wie Ihre index.php zu erzwingen
Bitte als Bild anhängen, hinzufügen vor allen anderen Regelnsetting ssl .htaccess

5
Quy Le

in IndexController.php setzen

public function getIndex(Request $request)
{
    if ($request->server('HTTP_X_FORWARDED_PROTO') == 'http') {

        return redirect('/');
    }

    return view('index');
}

in AppServiceProvider.php setzen

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

}

In AppServiceProvider.php wird jede Weiterleitung an die URL https gesendet. Für http-Anfragen benötigen wir eine einmalige Weiterleitung. In IndexController.php müssen wir nur eine einmalige Weiterleitung durchführen

3
Artur Qaramyan

Die obigen Antworten haben bei mir nicht funktioniert, aber Deniz Turan hat den .htaccess anscheinend so umgeschrieben, dass er mit Herokus Load Balancer hier funktioniert: https://www.jcore.com/2017/01/29/https-on-heroku-using-htaccess erzwingen /

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

Für Laravel 5.6 musste ich den Zustand ein wenig ändern, damit es funktionierte.

von:

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

Zu:

if (empty($_SERVER['HTTPS']) && env('APP_ENV') === 'prod') {
return redirect()->secure($request->getRequestUri());
}
1
Priyank

Das hat für mich geklappt. Ich habe einen benutzerdefinierten PHP-Code erstellt, um die Weiterleitung an https zu erzwingen. Fügen Sie diesen Code einfach in die header.php ein

<?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
Geeky Ashim

Wenn Sie CloudFlare verwenden, können Sie einfach eine Seitenregel erstellen, um immer HTTPS zu verwenden: Force SSL Cloudflare Dadurch wird jede http: // - Anforderung an https: // umgeleitet.

Darüber hinaus müssten Sie Ihrer boot () -Funktion\app\Providers\AppServiceProvider.php Folgendes hinzufügen:

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

Dies würde sicherstellen, dass jeder Link/Pfad in Ihrer App https: // anstelle von http: // verwendet.

1
butaminas

So geht's auf Herok

Fügen Sie zum Erzwingen von SSL auf Ihren Dynos, jedoch nicht lokal, das Ende Ihres .htaccess in public/hinzu:

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

Sie können dies auf Ihrem lokalen Computer testen mit:

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

Hierdurch wird der Header X-weitergeleitet und auf die Form gebracht, die er für Heroku annehmen wird.

es wird simuliert, wie ein Heroku-Dyno eine Anfrage sieht.

Sie erhalten diese Antwort auf Ihrem lokalen 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>

Das ist eine Umleitung. Das ist es, was Heroku einem Client zurückgibt, wenn Sie den .htaccess wie oben eingestellt haben. Auf Ihrem lokalen Computer ist dies jedoch nicht der Fall, da X-Forwarding nicht aktiviert ist (wir haben es mit einer Kräuselung oben vorgetäuscht, um zu sehen, was passiert ist).

1
mwal

Ein etwas anderer Ansatz, getestet 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
Zoli

Ich verwende in Laravel 5.6.28 folgende Middleware:

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
fomvasss

Der einfachste Weg wäre auf der Anwendungsebene. In der Datei

app/Providers/AppServiceProvider.php

fügen Sie Folgendes hinzu:

use Illuminate\Support\Facades\URL;

und fügen Sie in der boot () -Methode Folgendes hinzu:

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

Dadurch sollten alle Anforderungen auf Anwendungsebene an https umgeleitet werden.

(Hinweis: Dies wurde mit laravel 5.5 LTS) getestet.)

1
Pinak Saha

Ich füge diese Alternative hinzu, da ich unter diesem Problem sehr gelitten habe. Ich habe alle möglichen Wege ausprobiert und nichts hat funktioniert. Also habe ich einen Workaround dafür gefunden. Es ist vielleicht nicht die beste Lösung, aber es funktioniert -

Zu Ihrer Information, ich verwende Laravel 5.6

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

production <- Es sollte durch den APP_ENV-Wert in Ihrer .env-Datei ersetzt werden

1
thebrownkid