Laravel 4 Laravel将所有请求重定向到HTTPS

Laravel 4 Laravel将所有请求重定向到HTTPS,laravel-4,Laravel 4,我们的整个网站将通过https提供服务。我在每条路线上都有“https”。但是,如果他们试图通过http将其重定向到https,我该如何将其重定向到https Route::group(array('https'), function() { // all of our routes } 使用App::before 您可能能够利用App/filters.php文件中的App::before()块 更改块以包含一个简单的检查,查看当前请求是否安全,如果不安全,则重定向它 App::be

我们的整个网站将通过https提供服务。我在每条路线上都有“https”。但是,如果他们试图通过http将其重定向到https,我该如何将其重定向到https

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

使用App::before

您可能能够利用
App/filters.php
文件中的
App::before()

更改块以包含一个简单的检查,查看当前请求是否安全,如果不安全,则重定向它

App::before(function($request)
{
    if( ! Request::secure())
    {
        return Redirect::secure(Request::path());
    }
});
使用过滤器

另一种选择可能是创建这样的过滤器。人们通常也将其存储在
app/filters.php

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

});
然后,您可以像这样对任何路由、路由组或控制器强制执行该新筛选器

个别路线

路线组

控制器

您需要在控制器的
\u construct()
方法中执行此操作

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

另一个答案可能是让web服务器处理这个问题。如果您使用的是Apache,则可以使用RedirectSSL功能确保所有请求都将发送到站点的HTTPS版本,如果没有,则可以重定向它们。这将在拉威尔收到请求之前发生

如果您使用的是NGINX,那么可以通过使用两个服务器块来实现这一点。一个用于端口80上的正常HTTPS,另一个用于端口443上的HTTPS。然后将普通服务器块配置为始终重定向到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.
}

我个人会选择这个选项,因为PHP本身不需要处理任何事情。在web服务器级别处理这样的检查通常比较便宜。

如果您有问题,由于某种原因,
Request::secure()
返回false,即使url是
https
,也可能是因为$\u server['https']值不存在

这是一个解决方法:

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

我在执行POST请求时遇到了强制ssl的问题。它将始终重定向以获取。这是因为默认情况下,
Redirect::secure()
使用302重定向

要确保POST请求被正确重定向,请使用以下命令

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

这将确保在重定向发生后,您的请求将保留原始请求方法

结合以前的答案并更新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');

我不太了解HTTP和HTTPS的细节,所以如果这个答案不是很好,我很抱歉

我的理解是,存在一个问题,即即使客户端和(客户端指定的)服务器使用HTTPS,
Request::secure()
也可能返回false,因为您的应用程序可能运行在另一台服务器上,而该服务器可能没有接收HTTPS请求

我在heroku中托管我的laravel应用程序,它似乎做到了这一点。我的猜测是,主(客户机指定的)服务器是一个负载平衡器,当请求被转发时,它作为一个正常的HTTP请求到达另一个服务器

当发生这种转发时,您不应该只检查
Request::secure()
是否为
true
。(由#laravel@irc.freenode.com中的某人指示)我也要检查
Request::server('HTTP#X#u PROTO')
,看看它是否等于
'https'


因此,如果您打算遵循此处的其他建议并在不安全的情况下执行重定向,请尝试检查此服务器参数。

使用.htaccess Apache for laravel 4.2.X

原始文件

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

    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]
</IfModule>

选项-多视图
重新启动发动机
#重定向尾部斜杠。。。
重写规则^(.*)/$/$1[L,R=301]
#处理前控制器。。。
重写cond%{REQUEST_FILENAME}-D
重写cond%{REQUEST_FILENAME}-F
重写规则^index.php[L]
编辑文件/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>

选项-多视图
重新启动发动机
#重定向尾部斜杠。。。
重写条件%{HTTPS}关闭
重写规则^(.*)$https://%{HTTP_HOST}%{REQUEST_URI}[L,R=301]
#处理前控制器。。。
重写cond%{REQUEST_FILENAME}-D
重写cond%{REQUEST_FILENAME}-F
重写规则^index.php[L]

如果代理和请求背后的::secure()不起作用

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

结合前面的答案,使用Laravel 4.2中提供的常量和方法

routes.php

Route::when('*', 'secure');
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
        );
    }
});
filters.php

Route::when('*', 'secure');
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
        );
    }
});

对于使用Laravel 4/5和Elastic Beanstalk的用户,使用这些方法强制使用HTTPS是很困难的,因为
IsSecurity()
将返回
false
。此外,使用
.htaccess
重定向将导致Chrome的重定向循环,并延迟Firefox中的页面加载时间

此设置是为

  • Laravel 5和可能为Laravel 3/4工作
  • 加载到运行EC2服务器实例的Elastic Beanstalk上的应用程序
  • 用于DNS解析的路由53
  • Cloudfront用于所有资产的全局CDN和强制HTTPS
  • 我在Windows计算机上运行aws。Linux可能略有不同
经过数小时的尝试,我成功地通过以下步骤将所有HTTP请求转发到HTTPS:

  • 获取SSL证书。指南和提供者很多,可以通过谷歌搜索找到

  • 使用console命令将证书上载到AWS。指挥结构是:

    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/
    
  • 创建一个弹性Beanstalk应用程序。继续执行设置过程。安装应用程序后,转到配置->网络层->负载平衡,然后单击齿轮图标

  • 选择安全侦听器端口作为443。选择协议作为HTTPS。从步骤2中为SSL证书ID选择
    证书名称。保存配置

  • 转到您的控制台。单击EC2实例。单击负载平衡器。点击t
    php artisan make:middleware EB_SSL_Trust
    
        public function handle($request, Closure $next)
        {
            $request->setTrustedProxies( [ $request->getClientIp() ] );
            return $next($request);
        }
    
        protected $middleware = [
            ...
            'App\Http\Middleware\EB_SSL_Trust',
            ...
        ];
    
    App::before(function($request)
    {
        if( ! Request::secure())
        {
             return Redirect::secure(Request::getRequestUri());
        }
    });
    
    $router->filter('force.ssl', function () {
          if ( ! request()->secure() ) {
               return redirect()->secure(request()->path());
          }
    });
    
    Route::group(['before' => 'force.ssl'], function () {
        // Routes here
    });
    
    App\Http\Providers\RouteServiceProvider@map
    
    public function handle($request, Closure $next)
    {
        if(! $request->secure()) {
            return redirect()->secure($request->path());
        }
        return $next($request);
    }
    
    // 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());
    });
    
    // app/routes.php
    Route::group(array('before' => 'ssl.force'), function () {
        // SSL routes
    });