如何通过 https 在 Laravel 5 中提供静态内容?

Posted

技术标签:

【中文标题】如何通过 https 在 Laravel 5 中提供静态内容?【英文标题】:How to serve static content in Laravel 5 over https? 【发布时间】:2016-09-27 19:47:37 【问题描述】:

我花了很多时间试图解决这个问题,但到目前为止还没有运气。由于混合内容错误,我的应用未加载 css(“https://example.com/”处的页面已通过 HTTPS 加载,但请求了不安全的样式表“http://example.com/assets/css/magazine.min.css”。此请求已被阻止;必须提供内容HTTPS)。我知道我可以通过将 true 传递给资产函数来加载资产,但这意味着我必须去所有资产调用并更改它们。是否有我可以配置的站点范围设置,以便它在生产中执行 https 而在本地执行 http?

谢谢

【问题讨论】:

只要你没有在任何地方使用URL::forceScheme,它应该根据请求的方案自动检测(并且你没有传递任何东西作为asset()的第二个参数) 我是否可以配置站点范围的设置,以便它在生产环境中使用 https 而在本地使用 http? - 嗯...中间件? 【参考方案1】:

您可以创建类似 ForceHttps 中间件的东西,然后在其中创建环境条件,如下所示:

public function handle($request, Closure $next)

    if (!\App::environment('local')) 
        \URL::forceSchema('https');
    

    return $next($request);

如果你愿意,不如将它添加到某个路由组或全局。

注意:我建议在您的网络服务器上解决此问题,而不是在 Laravel 中

【讨论】:

我也强烈建议在本地环境中使用 https。它是 Web 开发的重要组成部分,因此您也应该注意本地。当您只是在现场测试时,很容易错过一些东西。 这个问题很明确。无论如何,在某些本地环境中实现这一点可能有点复杂,但是当然可以,如果有本地自签名证书,请随意删除条件。【参考方案2】:

只需使用asset() helper 来生成资产的 URL。它将使用当前协议。

不要强制资产通过 https 加载,除非它们是敏感的(几乎从来没有这种情况)。这将是一笔开销,因为您通常更关心安全的网站内容而不是安全资产。换句话说,如果您接受加载 http 网站,您很可能接受了 http 资产。相反,请考虑在每个非安全请求上使用中间件将 http 重定向到 https。

这是我自己使用的中间件:

public function handle($request, Closure $next)

    if (!$request->secure()) 
        return redirect()->secure($request->getRequestUri());
    

    return $next($request);

如果您想使用它,请记住在附加任何 cookie 之前触发它,即在 Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse 中间件之前。

【讨论】:

您应该强制使用 HTTPS 保护所有内容,否则,未受保护的内容(css、javascript、图像)可以通过 mitm 攻击即时修改,甚至可以使用 CSS作为键盘记录器并破坏受保护的内容。 我没有说我们不应该保护内容。我说过我们不应该只为资产做这件事,因为最有害的修改发生在 html 上——毕竟那是内容。因此,在这种情况下,最好通过 HTTPS 为整个网站提供服务,asset() 助手也会使资产的 URL 成为 https。如果他不为网站使用 HTTPS,那么他可能无论如何都不关心安全性,所以我不明白为什么有人会通过 https 只提供 CSS、JS 或图像。我希望我现在更清楚了。【参考方案3】:

我创建了 app/Helpers/SiteHelpers.php,其中包含一个覆盖默认 asset() 函数的函数。

<?php

/**
 * Overrides the default asset() method, which generates an asset path for the application.
 *
 * @param  string $path
 * @param  bool   $secure
 *
 * @return string
 */
function asset ($path, $secure = null) 
    if (Request::server('HTTP_X_FORWARDED_PROTO') == 'https' || Request::server('HTTPS') == 'on') 
        $secure = TRUE;
    

    return app('url')->asset($path, $secure);

然后将其添加到bootstrap/autoload.php 上方的require __DIR__.'/../vendor/autoload.php'; 上,如下所示:

require __DIR__.'/../app/Helpers/SiteHelpers.php';
require __DIR__.'/../vendor/autoload.php';

这很灵活,具体取决于您是在 http 还是 https 上提供静态内容

【讨论】:

以上是关于如何通过 https 在 Laravel 5 中提供静态内容?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - 让 laravel 5 应用使用 https

如何在 laravel 5.4 中实现 HTTPS

如何通过 post 方法将数据从 ajax 传递到 laravel 5.2 控制器

Laravel:如何通过家长控制在 http 和 https 之间切换?

如何通过composer安装laravel框架

Laravel 5 - 重定向到 HTTPS