Laravel redirige toutes les requêtes vers HTTPS

notre site entier doit être servi sur https. J'ai des' https ' dans chaque route. Cependant, Comment puis-je les rediriger vers https s'ils tentent de le faire via http?

Route::group(array('https'), function()
{
     // all of our routes
}
58
demandé sur Sajan Parikh 2013-11-14 05:24:43

15 réponses

utilisant App:: avant

vous pourriez être en mesure de profiter du bloc App::before() dans le fichier app/filters.php .

changez le bloc pour inclure une simple vérification pour voir si la requête actuelle est sécurisée, et si non, redirigez-la.

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

Utilisant Des Filtres

une Autre option pourrait être de créer un filtre comme si. En général, les gens conservez-le également dans app/filters.php .

Route::filter('force.ssl', function()
{
    if( ! Request::secure())
    {
        return Redirect::secure(Request::path());
    }

});

vous pouvez alors appliquer ce nouveau filtre à l'une de vos routes, groupes de routes, ou contrôleurs comme ceci.

Route Individuelle

Route::get('something', ['before' => 'force.ssl'], function()
{
    return "This will be forced SSL";
});

Groupe De Route

Route::group(['before' => 'force.ssl'], function()
{
    // Routes here.
});

contrôleur

vous aurez besoin de le faire dans votre controller __construct() la méthode.

public function __construct()
{
    $this->beforeFilter('force.ssl');
}
93
répondu Sajan Parikh 2016-06-08 08:32:56

une Autre réponse pourrait être de laisser votre serveur web. Si vous utilisez Apache, vous pouvez utiliser la fonctionnalité RedirectSSL pour vous assurer que toutes les requêtes sont acheminées vers la version HTTPS de votre site, et si vous ne les redirigez pas. Cela se produira avant même Laravel obtenir la demande.

Apache RedirectSSL

si vous êtes sur NGINX, vous pouvez accomplir ceci en ayant deux blocs de serveur. Un pour les HTTPS normaux sur le port 80, et un autre pour HTTPS sur le port 443. Ensuite, configurez le bloc normal du serveur pour toujours rediriger vers la version 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.
}

j'utiliserais Personnellement cette option car PHP lui-même n'a pas à traiter quoi que ce soit. Il est généralement moins coûteux de traiter une vérification comme celle-ci au niveau du serveur web.

33
répondu Sajan Parikh 2013-11-14 03:05:55

pour les utilisateurs utilisant Laravel 4/5 et Elastic Beanstalk, forcer les HTTPS est difficile en utilisant ces méthodes parce que le isSecure() retournera false . De plus, l'utilisation des redirections .htaccess se traduira par une boucle de redirection Pour Chrome et des temps de chargement de page retardés dans Firefox.

C'est pour

  • Laravel 5 et peut travailler pour Laravel 3 / 4
  • application chargée sur la tige élastique tournant EC2 instances de serveur
  • Route 53 utilisée pour la résolution DNS
  • Cloudfront utilisé pour Global CDN de tous les actifs et application HTTPS
  • je cours aws sur une machine Windows. Linux peut varier légèrement?

après des heures de travail, j'ai réussi à transmettre toutes les requêtes HTTP à HTTPS en suivant les étapes suivantes:

  1. obtenir une SSL certificat. Les Guides et les fournisseurs sont nombreux et peuvent être trouvés via une recherche Google.

  2. Téléchargez le certificat sur AWS en utilisant la commande aws console command. La structure de commande est:

    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/
    
  3. créer une application élastique en haricot magique. Procédez au processus de configuration. Une fois l'application configurée, passez à Configuration - > Réseau de Niveau -> Load Balancing et cliquez sur icône d'engrenage .

  4. sélectionner Port d'écoute Sécurisé as 443 . Sélectionnez protocole comme HTTPS . Sélectionnez le CERTIFICATE_NAME de étape 2 pour numéro de certificat SSL . Enregistrez le configuration.

  5. allez à votre Console . Cliquez sur EC2 Instances . Cliquez Sur Load Balancers . Cliquez sur les équilibreurs de charge. Cliquez sur Instances et faites défiler vers le bas pour voir les instances EC2 affectées à cet équilibreur de charge. Si L'instance EC2 a le même nom que L'URL de votre Application( ou quelque chose de proche), prenez note du nom DNS pour le répartiteur de charge. Il doit être dans le format awseb-e-...

  6. retournez à votre Console . Cliquez Sur CloudFront . Cliquez Sur Créer Une Distribution . Sélectionnez une distribution Web .

  7. mettre en place la distribution. Définissez votre nom de domaine D'origine à la charge balancer nom DNS que vous avez trouvé dans étape 5 . Définissez la Politique de protocole de visionneuse à rediriger HTTP vers HTTPS . Set en Avant les Chaînes de Requête à Oui . Définissez Alternate Domain Names (CNAMEs) à L'URL(s) que vous souhaitez utiliser pour votre application. Mettez certificat SSL sur le CERTIFICATE_NAME que vous avez téléchargé dans étape 2 . Créez votre distribution.

  8. cliquez sur le nom de votre distribution dans CloudFront. Cliquez sur Origines , sélectionnez votre origine, et cliquez sur Modifier . Assurez-vous que votre Politique de protocole D'origine est affichage de correspondance . Revenir en arrière. Cliquez sur Comportements , sélectionnez votre origine, et cliquez sur Modifier . Changement En-têtes avant à Whitelist et ajouter Host . Enregistrer.

  9. allez à votre Console . Cliquez Sur Route 53 . Cliquez Sur Zones Hébergées . Cliquez Sur Pour Créer La Zone Hébergée . Configurer votre nom de domaine. Une fois configuré, cliquez sur . Entrez votre enregistrement. Sélectionner Alias comme Oui . Votre Alias cible est votre distribution CloudFront. Enregistrez le disque.

  10. mettez en place vos serveurs de noms pour votre domaine pour pointer vers les serveurs de noms de Route 53. Attendre que tout se propage, ce qui pourrait prendre quelques heures. Allez à votre URL. Vous serez automatiquement redirigé vers HTTPS.

  11. "Mais attendez, mon les liens ne vont pas vers HTTPS!?"Vous devez gérer l'en-tête X-Forwarded-Proto que CloudFront passera. Pour Laravel 4, suivre ce guide . Pour Laravel 5, Lancez ceci:

    php artisan make:middleware EB_SSL_Trust
    

et ajoutez ceci au fichier EB_SSL_Trust :

    public function handle($request, Closure $next)
    {
        $request->setTrustedProxies( [ $request->getClientIp() ] );
        return $next($request);
    }

et ajoutez ceci à votre fichier App\Http\Kernel.php :

    protected $middleware = [
        ...
        'App\Http\Middleware\EB_SSL_Trust',
        ...
    ];

Note: tous vos biens, tels que CSS, JS ou images doivent être envoyés via le protocole HTTPS. Si vous utilisez Laravel pour créer ces liens, utilisez secure_asset() pour créer L'URL HTTPS dans votre vue.

12
répondu Adam Link 2015-03-20 17:40:47

à l'Aide .htaccess Apache pour laravel 4.2.X

Fichier Original

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ / [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Modifier le Fichier /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>
7
répondu urielOn 2016-01-23 21:20:29

L'utilisation de filtres a été dépréciée dans Laravel 5.1.* . C'est un travail parfait pour un MiddleWare.

créer un Middleware et dans la section de la poignée mettre

public function handle($request, Closure $next)
{
    if(! $request->secure()) {
        return redirect()->secure($request->path());
    }
    return $next($request);
}

ensuite, enregistrez simplement votre middleware dans votre noyau.php et utilisez-le avec vos routes ou vos controllers.

6
répondu prog_24 2016-04-05 09:51:16

combinaison des réponses précédentes et mise à jour pour 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');
5
répondu bishop 2014-08-27 13:22:12

si vous voulez rediriger vers la même URL mais en utilisant https, vous devez utiliser Request::getRequestUri() au lieu de Request::path() :

App::before(function($request)
{
    if( ! Request::secure())
    {
         return Redirect::secure(Request::getRequestUri());
    }
});
3
répondu ggonzal 2015-09-02 15:24:56

si vous avez un problème, où pour une raison quelconque Request::secure() retourne false, même si l'url est https , cela pourrait être parce que la valeur $_SERVER['HTTPS'] n'existe pas.

c'est une solution:

App::before(function ($request){
    // Force https
    if(!Request::secure() && array_get($_SERVER, 'SERVER_PORT') != 443){
        return Redirect::secure(Request::path());
    }
});
1
répondu Mārtiņš Briedis 2014-06-26 08:34:12

j'ai eu un problème avec le fait de forcer ssl tout en faisant la demande POST. Il serait toujours rediriger pour obtenir. Cela se produit parce que Redirect::secure() est par défaut en utilisant une redirection 302.

pour vous assurer que votre requête POST est redirigée correctement, utilisez quelque chose comme

return Redirect::secure("your/path/here", 307)

cela vous permettra de vous assurer que votre requête conservera la méthode de requête originale après que la redirection se produit.

1
répondu MikeWu 2014-08-13 13:58:17

Je ne comprends pas en détail HTTP et HTTPS, donc je suis désolé si cette réponse n'est pas très bonne.

je crois comprendre qu'il y a un problème que même lorsque le client et le serveur (spécifié par le client) utilisent HTTPS, Request::secure() peut retourner false parce que votre application peut fonctionner sur un serveur différent, qui ne reçoit peut-être pas de requête https.

j'héberge mon application laravel à heroku et il semble qu'elle le fasse. Mon guess est que le serveur principal (spécifié par le client) est un équilibreur de charge et que lorsque la requête est transmise, elle arrive à l'autre serveur comme une requête HTTP normale.

quand une telle expédition peut se produire, vous ne devriez pas simplement vérifier que Request::secure() est true . J'ai été demandé (par quelqu'un dans #laravel @ irc.freenode.com) cochez également Request::server('HTTP_X_FORWARDED_PROTO') pour voir si elle est égale à 'https' .

Donc, si vous avez l'intention de suivre les autres conseils ici et d'effectuer une redirection en cas de non-sécurisé, essayez de vérifier pour ce paramètre de serveur aussi.

1
répondu Pedro Henrique A. Oliveira 2014-08-26 22:06:44

pour laravel 5.1 vous devez utiliser le code indiqué dans App\Http\Providers\RouteServiceProvider@boot

$router->filter('force.ssl', function () {
      if ( ! request()->secure() ) {
           return redirect()->secure(request()->path());
      }
});

Maintenant vous pouvez l'utiliser dans le fichier routes.

Route::group(['before' => 'force.ssl'], function () {
    // Routes here
});

vous pouvez aussi ajouter ['before' => 'force.ssl'] dans $router->group() dans

App\Http\Providers\RouteServiceProvider@map
1
répondu Muhammad Abdullah 2017-02-01 14:48:04

cela a fonctionné pour moi dans Apache 2.4

j'ai changé .htaccess dans le dossier racine de Laravel

de <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)$ public/ [L] </IfModule>

à <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteRule ^(.*)$ public/ [L] </IfModule>

1
répondu varun sharma 2017-07-27 18:13:10

si derrière un proxy et une requête::secure() ne fonctionne pas.

App::before( function( $request )
{
  // set the current IP (REMOTE_ADDR) as a trusted proxy
  Request::setTrustedProxies( [ $request->getClientIp() ] );
});
0
répondu Carsten Jonstrup 2014-12-05 19:58:37

combinaison des réponses précédentes pour utiliser les constantes et les méthodes disponibles dans Laravel 4.2.

itinéraires.php

Route::when('*', 'secure');

filtres.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
        );
    }
});
0
répondu user161875 2015-01-20 19:57:27

si vous devez utiliser Laravel 4 lui-même pour gérer la redirection (comme moi), j'opterais pour la configuration suivante (explication sous forme de commentaires dans le code):

filtre de Route:

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

ensuite, appliquez le filtre comme un avant Filtre à votre route ou groupe de route. par exemple:

// app/routes.php
Route::group(array('before' => 'ssl.force'), function () {
    // SSL routes
});
0
répondu Jones03 2016-05-11 04:02:06