如何通过 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
如何通过 post 方法将数据从 ajax 传递到 laravel 5.2 控制器