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
}
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');
}
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.
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.
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:
-
obtenir une SSL certificat. Les Guides et les fournisseurs sont nombreux et peuvent être trouvés via une recherche Google.
-
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/
-
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 .
-
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. -
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-...
-
retournez à votre Console . Cliquez Sur CloudFront . Cliquez Sur Créer Une Distribution . Sélectionnez une distribution Web .
-
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. -
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.
-
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.
-
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.
-
"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.
à 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>
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.
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');
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());
}
});
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());
}
});
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.
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.
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
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>
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() ] );
});
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
);
}
});
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
});