redireccionar htaccess habilitar forceschema force configurar php laravel laravel-routing laravel-5

php - htaccess - redireccionar de http a https en laravel



Laravel 5: redirigir a HTTPS (18)

¿Qué pasa con el uso del archivo .htaccess para lograr la redirección https? Esto debe colocarse en la raíz del proyecto (no en la carpeta pública). Su servidor debe estar configurado para apuntar al directorio raíz del proyecto.

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

Lo uso para laravel 5.4 (última versión en el momento de escribir esta respuesta) pero debería seguir funcionando para las versiones de funciones incluso si laravel cambia o elimina alguna funcionalidad.

Trabajando en mi primer proyecto de Laravel 5 y no estoy seguro de dónde o cómo colocar la lógica para forzar HTTPS en mi aplicación. El factor decisivo aquí es que hay muchos dominios que apuntan a la aplicación y solo dos de cada tres usan SSL (el tercero es un dominio alternativo, una larga historia). Así que me gustaría manejar esto en la lógica de mi aplicación en lugar de .htaccess.

En Laravel 4.2 logré la redirección con este código, ubicado en los filters.php :

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

Estoy pensando que Middleware es donde debería implementarse algo como esto, pero no puedo entender esto usándolo.

¡Gracias!

ACTUALIZAR

Si está utilizando Cloudflare como yo, esto se logra al agregar una nueva regla de página en su panel de control.


Alternativamente, si está usando Apache, puede usar el archivo .htaccess para imponer sus URL para usar el prefijo https . En Laravel 5.4, agregué las siguientes líneas a mi archivo .htaccess y funcionó para mí.

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


Esto es para Larave 5.2.xy superior. Si desea tener una opción para servir algún contenido a través de HTTPS y otros a través de HTTP, esta es una solución que funcionó para mí. Quizás se pregunte, ¿por qué alguien querría servir solo contenido a través de HTTPS? ¿Por qué no servir todo a través de HTTPS?

Aunque, está totalmente bien servir todo el sitio a través de HTTPS, cortar todo a través de HTTPS tiene una sobrecarga adicional en su servidor. Recuerde que el cifrado no es barato. La ligera sobrecarga también tiene un impacto en el tiempo de respuesta de su aplicación. Se podría argumentar que el hardware básico es barato y el impacto es insignificante, pero me estoy desviando :) No me gusta la idea de publicar páginas grandes de contenido de marketing con imágenes, etc. a través de https. Así que aquí va. Es similar a lo que otros han sugerido anteriormente usando middleware, pero es una solución completa que le permite alternar entre HTTP / HTTPS.

Primero crea un middleware.

php artisan make:middleware ForceSSL

Así es como debería verse su middleware.

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

Tenga en cuenta que no estoy filtrando en función del entorno porque tengo una configuración HTTPS para el desarrollo local y la producción, por lo que no es necesario.

Agregue lo siguiente a su routeMiddleware / App / Http / Kernel.php para que pueda elegir qué grupo de ruta debe forzar 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, ];

A continuación, me gustaría asegurar el inicio de sesión / registro de dos grupos básicos, etc. y todo lo demás detrás de 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 });

Confirme que sus middlewares se aplican a sus rutas correctamente desde la consola.

php artisan route:list

Ahora que ha asegurado todos los formularios o áreas sensibles de su aplicación, la clave ahora es usar su plantilla de vista para definir sus enlaces seguros y públicos (no https).

Según el ejemplo anterior, representaría sus enlaces seguros de la siguiente manera:

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

Los enlaces no seguros se pueden representar como

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

Lo que esto hace es generar una URL totalmente calificada, como https://yourhost/login y http://yourhost/aboutus

Si no se renderizó una URL totalmente calificada con http y usó una URL de enlace relativa (''/ aboutus''), entonces https persistiría después de que un usuario visite un sitio seguro.

¡Espero que esto ayude!


Esto funcionó para mí. Hice un código php personalizado para forzar la redirección a https. Solo incluye este código en el header.php

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


Estoy agregando esta alternativa ya que sufrí mucho con este problema. Lo intenté de diferentes maneras y nada funcionó. Entonces, se me ocurrió una solución alternativa. Puede que no sea la mejor solución, pero funciona.

FYI, estoy usando Laravel 5.6

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

production <- Debe reemplazarse con el valor APP_ENV en su archivo .env


Estoy usando el siguiente middleware de 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); } }


La forma más fácil sería a nivel de aplicación. En el archivo

app/Providers/AppServiceProvider.php

agregue lo siguiente:

use Illuminate/Support/Facades/URL;

y en el método boot () agregue lo siguiente:

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

Esto debería redirigir todas las solicitudes a https en el nivel de aplicación.

(Nota: esto ha sido probado con laravel 5.5 LTS)


Las respuestas anteriores no funcionaron para mí, pero parece que Deniz Turan reescribió el .htaccess de una manera que funciona con el equilibrador de carga de Heroku aquí: 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]


Otra opción que funcionó para mí, en AppServiceProvider, coloque este código en el método de arranque:

/URL::forceScheme(''https'');

La función escrita antes de forceScheme (''https'') era incorrecta, su forceScheme


Para Laravel 5.6, tuve que cambiar un poco la condición para que funcione.

de:

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

A:

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


Puede hacer que funcione con una clase de Middleware. Déjame darte una 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); } }

Luego, aplique este middleware a cada solicitud agregando la configuración de la regla en el archivo Kernel.php , de esta manera:

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

En el ejemplo anterior, el middleware redirigirá cada solicitud a https si:

  1. La solicitud actual viene sin protocolo seguro (http)
  2. Si su entorno es igual a la production . Por lo tanto, solo ajuste la configuración según sus preferencias.

Flama de nube

Estoy usando este código en un entorno de producción con un WildCard SSL y el código funciona correctamente. Si && App::environment() === ''production'' y lo pruebo en localhost, la redirección también funciona. Por lo tanto, tener o no un SSL instalado no es el problema. Parece que debe prestar mucha atención a su capa Cloudflare para ser redirigido al protocolo Https.

Editar 23/03/2015

Gracias a la @Adam Link de @Adam Link : es probable que sea causado por los encabezados que Cloudflare está pasando. Es probable que CloudFlare llegue a su servidor a través de HTTP y pase un encabezado X-Fordered-Proto que declara que está reenviando una solicitud HTTPS. Necesita agregar otra línea en su Middleware que diga ...

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

... confiar en los encabezados que CloudFlare está enviando. Esto detendrá el bucle de redireccionamiento

Editar 27/09/2016 - Laravel v5.3

Solo necesito agregar la clase de middleware en web grupo web en el 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 ], ];

Recuerde que web grupo web se aplica a todas las rutas de forma predeterminada, por lo que no necesita configurar la web explícitamente en rutas ni controladores.

Editar 23/08/2018 - Laravel v5.7

  • Para redirigir una solicitud según el entorno, puede usar App::environment() === ''production'' . Para la versión anterior era env(''APP_ENV'') === ''production'' .
  • Usando /URL::forceScheme(''https''); en realidad no redirige. Simplemente crea enlaces con https:// una vez que se muestra el sitio web.

Puede usar RewriteRule para forzar ssl en .htaccess misma carpeta con su index.php
Por favor agregue como imagen adjunta, agréguela antes de que todas las demás


Si usa CloudFlare, puede crear una regla de página para usar siempre HTTPS: Esto redirigirá cada solicitud http: // a https: //

Además de eso, también tendría que agregar algo como esto a su función / app / Providers / AppServiceProvider.php boot ():

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

Esto garantizaría que cada enlace / ruta en su aplicación esté usando https: // en lugar de http: //.


Similar a la respuesta de manix pero en un solo lugar. Middleware para forzar 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); } }


Un enfoque un poco diferente, probado en 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); } }


en IndexController.php poner

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

en AppServiceProvider.php poner

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

}

En AppServiceProvider.php, cada redireccionamiento irá a la URL https y para la solicitud http necesitamos una vez redirigir, así que en IndexController.php Solo necesitamos hacer una vez redireccionar


para laravel 5.4 use este formato para obtener la redirección https en lugar de .htaccess

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


Aquí se explica cómo hacerlo en Heroku

Para forzar SSL en su banco de pruebas pero no localmente, agregue al final de su .htaccess en público /:

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

Puede probar esto en su máquina local con:

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

Eso establece el encabezado X-reenviado a la forma que tomará en heroku.

es decir, simula cómo un dyno heroku verá una solicitud.

Obtendrá esta respuesta en su máquina local:

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

Esa es una redirección. Eso es lo que Heroku le devolverá a un cliente si configura el .htaccess como se indicó anteriormente. Pero no sucede en su máquina local porque no se configurará el reenvío de X (lo falsificamos con el rizo arriba para ver qué estaba sucediendo).