Laravel将所有请求重定向到HTTPS

jul*_*ver 60 laravel-4

我们的整个网站都将通过https提供服务.我在每条路线都有'https'.但是,如果他们通过http尝试将其重定向到https?

Route::group(array('https'), function()
{
     // all of our routes
}
Run Code Online (Sandbox Code Playgroud)

Saj*_*ikh 95

使用App ::之前

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

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

App::before(function($request)
{
    if( ! Request::secure())
    {
        return Redirect::secure(Request::path());
    }
});
Run Code Online (Sandbox Code Playgroud)

使用过滤器

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

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

});
Run Code Online (Sandbox Code Playgroud)

然后,您可以将此新过滤器强制实施到此类路线,路线组或控制器.

个人路线

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

路线组

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

调节器

您需要在控制器的__construct()方法中执行此操作.

public function __construct()
{
    $this->beforeFilter('force.ssl');
}
Run Code Online (Sandbox Code Playgroud)

  • 对于**Laravel 5及以上**,请查看此解决方案http://stackoverflow.com/a/28403907/1340784 (5认同)
  • 使用Request :: path(),而不是Request :: getRequestUri() (4认同)
  • 我正在使用这种方法,但在我运行`apt-get upgrade`后它突然停止了工作.现在我收到一个路由错误:"在1528行的vendor/laravel/framework/src/Illuminate/Routing/Router.php中的非对象上调用成员函数getAction()".如果我注释掉重定向,它可以正常工作. (2认同)

Saj*_*ikh 33

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

Apache RedirectSSL

如果您使用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.
}
Run Code Online (Sandbox Code Playgroud)

我个人会选择这个选项,因为PHP本身不需要处理任何事情.在Web服务器级别处理这样的支票通常更便宜.

  • 为了澄清,我认为这个答案是首选的做事方式而不是公认的答案. (3认同)
  • 我的理念:信任Web服务器重定向,但在应用程序中进行验证.通过这种方式,您可以获得两全其美的效果.当Web服务器为您完成此操作时,该应用程序不会遇到性能损失.当Web服务器没有(例如,配置错误)时,该应用程序充当安全网并且性能损失*非常值得*权衡. (3认同)

Ada*_*ink 12

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

这个设置是为了

  • Laravel 5可能适用于Laravel 3/4
  • 应用程序加载到运行EC2服务器实例的Elastic Beanstalk上
  • 路由53用于DNS解析
  • Cloudfront用于所有资产的全局CDN并强制执行HTTPS
  • aws在Windows机器上运行.Linux可能略有不同?

经过几个小时的尝试,我设法使用以下步骤将所有HTTP请求转发到HTTPS:

  1. 获取SSL证书.指南和提供商众多,可以通过Google搜索找到.

  2. 使用awsconsole命令将证书上载到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/
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建Elastic Beanstalk应用程序.继续完成设置过程.设置应用程序后,转到配置 - > 网络层 - > 负载平衡,然后单击齿轮图标.

  4. 选择安全侦听器端口443.选择Protocol as HTTPS.选择CERTIFICATE_NAME步骤2SSL证书ID.保存配置.

  5. 转到您的控制台.单击EC2实例.单击" 负载均衡器".单击负载平衡器.单击Instances并向下滚动以查看分配给该负载均衡器的EC2实例.如果EC2实例与您的应用程序URL具有相同的名称(或关闭的名称),请记下负载均衡器的DNS名称.它应该是格式awseb-e-...

  6. 返回您的控制台.单击CloudFront.单击创建分发.选择Web分配.

  7. 设置分发.将源域名设置为您在步骤5中找到的负载均衡器DNS名称.将查看器协议策略设置为将HTTP重定向到HTTPS.将" 查询字符串"设置为" 是".将备用域名(CNAME)设置为要用于应用程序的URL.将SSL证书设置为CERTIFICATE_NAME您在步骤2中上传的内容.创建您的发行版.

  8. 在CloudFront中单击您的分发名称.单击" 起源",选择原点,然后单击" 编辑".确保您的原始协议策略匹配查看器.回去.单击" 行为",选择您的原点,然后单击" 编辑".将转发标题更改为白名单并添加主机.保存.

  9. 转到您的控制台.单击Route 53.单击" 托管区域".单击" 创建托管区域".设置您的域名.设置完成后,单击" 创建记录集".输入您的A记录.选择别名.您的Alias Target是您的CloudFront分配.保存记录.

  10. 为您的域设置名称服务器以指向Route 53名称服务器.等待一切传播,这可能是几个小时.转到您的网址.您将自动重定向到HTTPS.

  11. "但等等,我的链接不会转到HTTPS!?" 您需要处理X-Forwarded-ProtoCloudFront将传递的标头.对于Laravel 4,请遵循本指南.对于Laravel 5,运行:

    php artisan make:middleware EB_SSL_Trust
    
    Run Code Online (Sandbox Code Playgroud)

然后将其添加到EB_SSL_Trust文件中:

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

并将其添加到您的App\Http\Kernel.php文件中:

    protected $middleware = [
        ...
        'App\Http\Middleware\EB_SSL_Trust',
        ...
    ];
Run Code Online (Sandbox Code Playgroud)

注意:您的所有资产(例如CSS,JS或图像)都需要通过HTTPS发送.如果您使用Laravel创建这些链接,请使用secure_asset()在View中创建HTTPS URL.


pro*_*_24 8

Laravel 5.1中不推荐使用过滤器.*.这对于MiddleWare来说是一个完美的工作.

创建一个中间件并在句柄部分放置

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

然后只需在Kernel.php中注册中间件,并将其与路由或控制器一起使用.


小智 7

使用.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>
Run Code Online (Sandbox Code Playgroud)

编辑文件/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>
Run Code Online (Sandbox Code Playgroud)

  • 但这并不会删除尾部斜杠.也许这个规则更合适:`RewriteRule ^(.*[^ /] |)/*$ https://%{HTTP_HOST}/$ 1 [L,R = 301]`.如果它不安全(有或没有斜杠),它会正确重定向.当协议正确但存在尾随斜杠时,还需要保持原始重定向. (2认同)

bis*_*hop 5

结合之前的答案和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');
Run Code Online (Sandbox Code Playgroud)