Laravel redirige todas las solicitudes a HTTPS

Nuestro sitio completo se servirá sobre https. Tengo ‘https’ en cada ruta. Sin embargo, ¿cómo los redirecciono a https si lo intentan a través de http?

Route::group(array('https'), function() { // all of our routes } 

Usando la aplicación :: antes

Es posible que pueda aprovechar el bloque App::before() en el archivo app/filters.php .

Cambia el bloque para incluir una simple comprobación para ver si la solicitud actual es segura, y si no, redirigirla.

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

Usando filtros

Otra opción podría ser crear un filtro como ese. La gente generalmente almacena esto también en app/filters.php .

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

Luego puede aplicar ese nuevo filtro a cualquiera de sus rutas, grupos de rutas o controladores como este.

Ruta individual

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

Grupo de ruta

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

Controlador

Tendrás que hacer esto en el método __construct() tu controlador.

 public function __construct() { $this->beforeFilter('force.ssl'); } 

Otra respuesta podría ser permitir que su servidor web maneje esto. Si está utilizando Apache, puede usar la función RedirectSSL para asegurarse de que todas las solicitudes vayan a la versión HTTPS de su sitio, y si no las redirecciona. Esto sucederá antes de que Laravel obtenga la solicitud.

Apache RedirectSSL

Si estás en NGINX, puedes lograr esto teniendo dos bloques de servidores. Uno para HTTPS normal en el puerto 80 y otro para HTTPS en el puerto 443. A continuación, configure el bloque de servidor normal para redireccionar siempre a la versión 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. } 

Yo personalmente iría con esta opción ya que PHP no tiene que procesar nada. En general es más barato procesar un cheque como este en el nivel del servidor web.

Para usuarios que usan Laravel 4/5 y Elastic Beanstalk, forzar HTTPS es difícil usando estos métodos porque isSecure() devolverá false . Además, el uso de .htaccess redirects dará como resultado un bucle de redirección para Chrome y retrasos en los tiempos de carga de la página en Firefox.

Esta configuración es para

  • Laravel 5 y puede funcionar para Laravel 3/4
  • Aplicación cargada en Elastic Beanstalk ejecutando instancias del servidor EC2
  • Ruta 53 utilizada para resolución de DNS
  • Cloudfront utilizado para CDN global de todos los activos y aplicación de HTTPS
  • aws en una máquina con Windows. Linux puede variar levemente?

Después de horas de mis propios bashs, logré obtener todas las solicitudes HTTP reenviadas a HTTPS utilizando los siguientes pasos:

  1. Obtenga un certificado SSL. Las guías y los proveedores son numerosos y se pueden encontrar a través de una búsqueda en Google.

  2. Suba el certificado a AWS utilizando el comando aws console. La estructura de comando es:

     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. Crea una aplicación Elastic Beanstalk. Continúe con el proceso de configuración. Una vez que la aplicación está configurada, vaya a Configuración -> Nivel de red -> Equilibrio de carga y haga clic en el ícono de ajustes .

  4. Seleccione Secure listener port como 443 . Seleccione Protocolo como HTTPS . Seleccione CERTIFICATE_NAME del paso 2 para la identificación del certificado SSL . Guarde la configuración.

  5. Ve a tu consola . Haga clic en Instancias EC2 . Haga clic en Load Balancers . Haga clic a través de los equilibradores de carga. Haga clic en Instancias y desplácese hacia abajo para ver las instancias EC2 asignadas a ese equilibrador de carga. Si la instancia EC2 tiene el mismo nombre que su URL de aplicación (o algo parecido), tome nota del nombre DNS para el equilibrador de carga. Debe estar en el formato awseb-e-...

  6. Regresa a tu consola . Haga clic en CloudFront . Haga clic en Crear distribución . Seleccione una distribución web .

  7. Configure la distribución. Establezca su nombre de dominio de origen en el nombre DNS del equilibrador de carga que encontró en el paso 5 . Establezca la Política del protocolo del visor para redirigir HTTP a HTTPS . Establezca cadenas de consulta hacia adelante en . Establezca Nombres de dominio alternativos (CNAME) en la (s) URL (s) que desee usar para su aplicación. Establezca el Certificado SSL en CERTIFICATE_NAME que cargó en el paso 2 . Crea tu distribución

  8. Haga clic en su nombre de distribución en CloudFront. Haga clic en Orígenes , seleccione su origen y haga clic en Editar . Asegúrese de que su política de protocolo de origen sea Match Viewer . Regresa. Haga clic en Comportamientos , seleccione su origen y haga clic en Editar . Cambie los encabezados hacia adelante a la lista blanca y agregue host . Salvar.

  9. Ve a tu consola . Haga clic en Ruta 53 . Haz clic en Zonas alojadas . Haga clic en Crear zona alojada . Configura tu nombre de dominio. Una vez configurado, haz clic en Crear conjunto de registros . Ingrese su registro A. Seleccione Alias como . Su objective Alias es su distribución CloudFront. Guarde el registro.

  10. Configure sus servidores de nombres para que su dominio apunte a los servidores de nombres de Route 53. Espere a que todo se propague, lo que podría ser unas pocas horas. Ve a tu URL Se te redireccionará automáticamente a HTTPS.

  11. “¡Pero espera, mis enlaces no van a HTTPS !?” Debe manejar el encabezado X-Forwarded-Proto que pasará CloudFront. Para Laravel 4, sigue esta guía . Para Laravel 5, ejecuta esto:

     php artisan make:middleware EB_SSL_Trust 

Y luego agregue esto al archivo EB_SSL_Trust :

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

Y App\Http\Kernel.php archivo App\Http\Kernel.php :

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

Nota: todos sus recursos, como CSS, JS o imágenes, deben enviarse a través de HTTPS. Si usa Laravel para crear estos enlaces, use secure_asset() para crear la URL HTTPS en su Vista.

Usando .htaccess Apache para laravel 4.2.X

Archivo original

   Options -MultiViews  RewriteEngine On # Redirect Trailing Slashes... RewriteRule ^(.*)/$ /$1 [L,R=301] # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L]  

Editar archivo /public/.htaccess

    Options -MultiViews  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]  

El uso de filtros ha quedado obsoleto en Laravel 5.1. * . Este es un trabajo perfecto para MiddleWare.

Cree un Middleware y en la sección de manejo coloque

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

Luego, simplemente registre su middleware en su Kernel.php y úselo con sus rutas o controladores.

Combinando respuestas previas y actualizando para 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 desea redireccionar a la misma URL pero usando https, debe usar Request::getRequestUri() lugar de Request::path() :

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

Si tiene un problema, donde por alguna razón Request::secure() devuelve falso, incluso cuando la URL es https , podría ser porque el valor $ _SERVER [‘HTTPS’] no existe.

Esta es una solución alternativa:

 App::before(function ($request){ // Force https if(!Request::secure() && array_get($_SERVER, 'SERVER_PORT') != 443){ return Redirect::secure(Request::path()); } }); 

Tuve un problema al forzar SSL mientras hacía la solicitud POST. Siempre redirigiría a GET. Esto sucede porque Redirect::secure() es por defecto usando un redireccionamiento 302.

Para asegurarse de que su solicitud POST se redirija correctamente, use algo como

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

Esto asegurará que su solicitud mantenga el método de solicitud original después de que se produzca la redirección.

No entiendo sobre HTTP y HTTPS en detalle, así que lo siento si esta respuesta no es muy buena.

Tengo entendido que hay un problema que incluso cuando el cliente y el servidor (especificado por el cliente) usan HTTPS, Request::secure() puede devolver falso porque su aplicación puede estar ejecutándose en un servidor diferente, que posiblemente no esté recibiendo una solicitud https .

Estoy alojando mi aplicación laravel en heroku y parece que lo hace. Mi suposición es que el servidor primario (especificado por el cliente) es un equilibrador de carga y cuando la solicitud se reenvía, llega al otro servidor como una solicitud HTTP normal.

Cuando tal reenvío puede suceder, no debe simplemente verificar que Request::secure() sea true . Fui instruido (por alguien en #laravel @ irc.freenode.com) para verificar también Request::server('HTTP_X_FORWARDED_PROTO') para ver si es igual a 'https' .

Entonces, si tiene la intención de seguir los otros consejos aquí y realizar un redireccionamiento en caso de que no sea seguro, intente también verificar este parámetro del servidor.

Para laravel 5.1, debe usar el código proporcionado en la App\Http\Providers\RouteServiceProvider@boot

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

Ahora puedes usar esto en el archivo de rutas.

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

también puede agregar ['before' => 'force.ssl'] en $router->group() en

 App\Http\Providers\RouteServiceProvider@map 

Esto funcionó para mí en Apache 2.4

Cambié .htaccess en la carpeta raíz de Laravel

De RewriteEngine On RewriteRule ^(.*)$ public/$1 [L]

Para RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteRule ^(.*)$ public/$1 [L]

Si está detrás de un proxy y Request :: secure () no está funcionando.

 App::before( function( $request ) { // set the current IP (REMOTE_ADDR) as a trusted proxy Request::setTrustedProxies( [ $request->getClientIp() ] ); }); 

Combinando respuestas previas para usar constantes y métodos que están disponibles en Laravel 4.2.

routes.php

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

filters.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 tiene que usar la propia Laravel 4 para manejar el redireccionamiento (como yo), iría para la siguiente configuración (explicación como comentarios en el código):

Filtro de ruta:

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

A continuación, aplique el filtro como filtro anterior a su ruta o grupo de rutas. p.ej:

 // app/routes.php Route::group(array('before' => 'ssl.force'), function () { // SSL routes }); 

Aquí hay una solución alternativa para Laravel 5.2.x o superior.

https://stackoverflow.com/a/39182378