如何修复 Laravel 请求/路由/url - 它认为 url 是 http,而实际上是 https

问题描述 投票:0回答:5

我的服务器使用 SSL,因此我的所有路由/网址都使用 https。我最近在 Laravel 5.7 中发现了一个错误,该错误在尝试使用电子邮件验证时暴露出来,该错误在带有 https 的服务器上不起作用。我不会详细讨论该问题,因为我还有另一个问题。我想保持这个简单。 我的 .env 文件中有以下设置:

APP_USE_HTTPS=true
APP_URL=https://www.example.com
APP_ENV=production

我在 AppServiceProvider 的 boot() 方法中有以下内容

    if (env('APP_USE_HTTPS')) {
        Log::info('AppServiceProvider: forcing URLs to use https');
        URL::forceScheme('https');
    }

这可能有点过头了,但为了尝试解决这个问题,我还将以下代码放在我的 web.php 路由文件的顶部”

if (env('APP_USE_HTTPS')) {
    Log::info('Routes: forcing URLs to use https');
    URL::forceScheme('https');
}

Route::get('/', 'PublicController@getHome');
Route::get('home', 'PublicController@getHome');

然后在我的 PublicController.getHome() 方法中我放入以下代码:

public function getHome()
{
    $currentPath= Request::fullUrl();
    Log::info($currentPath);

    return view('public.home');
}

现在我转到浏览器并在地址栏中输入:

https://www.example.com

我在日志文件中得到了这个:

AppServiceProvider: forcing URLs to use https
Routes: forcing URLs to use https
http://www.example.com

正如您从最后一条日志消息中看到的那样,laravel 始终使用 http 而不是 https 的事实开始产生问题。从签署的路线开始。我正在尝试使用内置电子邮件验证,但签名是使用 https 路由生成的,并且发送给用户的电子邮件的 URL 中确实有 https,用于返回同一服务器。然而,路由验证使用的是 http(即使使用了 https),因此它会生成不同的签名,因此所有验证链接都会失败并出现 403 错误。

我有什么遗漏的吗?我似乎找不到代码来显示 Laravel 如何知道使用 https 或 http,还是只是为 http 进行了硬编码?

感谢您给我的任何帮助。

*** 更新以显示 Shaielndra Gupta 答案的问题 ****

实现中间件后,下面是我使用的代码,但正如您将看到的,核心问题存在于处理 url 的所有方法中。例如:

$request->secure()

即使使用 https 也会返回 false。然后致电:

redirect()->secure($request->getRequestUri());

没有什么好处,因为这会导致路由再次循环回此方法,这仍然为 secure() 返回 false,基本上创建了一个无限循环(或无限太多的重定向)

class ForceHttpsProtocol {

public function handle($request, Closure $next) {
    Log::info('request uri: '.$request->fullUrl());
    Log::info('secure: '.($request->secure() ? 'yes' : 'no'));

    if (!$request->secure() && env('APP_USE_HTTPS')) {
        return redirect()->secure($request->getRequestUri());
    }

    return $next($request);
}

}

当您尝试访问任何页面 1 次时,即使使用 https://www.example.com

,上述代码的日志也会生成以下内容
request uri: http://www.example.com
secure: no
request uri: http://www.example.com
secure: no
request uri: http://www.example.com
secure: no
request uri: http://www.example.com
secure: no

< over and over till page times out >

laravel http https routes
5个回答
6
投票

经过大量研究,我终于发现问题所在。 我的实时服务器安装在 Amazon EC2 服务器上位于负载均衡器后面。 负载均衡器正在接收 (https) 请求并处理所有 SSL 要求,然后将请求作为 http 转发到我的网站。 为了解决这个问题,我必须安装 fideloper/TrustedProxy 包。这个包允许我的网站信任代理并获取请求的有效标头,因此它现在知道请求实际上是使用 https 发送的。

Laravel 写了一篇文章,准确地描述了我的情况。 https://laravel-news.com/trusted-proxy

这是我安装的包: https://github.com/fideloper/TrustedProxy


0
投票

如果有人在 apache 代理方面遇到困难并且

$request->server()

您可以通过在

AppServiceProvider

中添加此行来覆盖请求库默认行为

 $this->app['request']->server->set('HTTPS','on')


0
投票

有一个非常有用的方法: 设置:

$this->app['request']->server->set('HTTPS','on');

而不是:

URL::forceScheme('https');

只有这样才能将页面链接http转为https。 当使用代理时。


-1
投票

改变这个

APP_USE_HTTPS=true
APP_URL=https://www.example.com

到此

APP_URL=http://www.example.com
APP_USE_HTTPS=false

因为 Laravel 使用 APP_URL 来生成 url。


-1
投票

改变你的

config/session.php

'http_only' => true,

更改为

'http_only' => false,

或者制作一个中间件 HttpsProtocol.php

namespace MyApp\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\App;

class HttpsProtocol {

    public function handle($request, Closure $next)
    {
        if (!$request->secure() && App::environment() === 'production') 
        {
             return redirect()->secure($request->getRequestUri());
        }
        return $next($request); 
    }
}

然后,将此中间件应用于每个请求,并在

protected $routeMiddleware array
中的 Kernel.php 文件中添加设置规则,

'https'=>App\Http\Middleware\HttpsProtocol::class
© www.soinside.com 2019 - 2024. All rights reserved.