每当我在
生产上访问使用
temporarySignedRoute()
创建的 URL 时,它都会抛出 InvalidSignatureException
。但是,在 dev 环境中,它可以工作。我也尝试过使用 signedRoute()
但没有成功。
我正在创建这样的网址:
\URL::temporarySignedRoute(
'user.activate',
now()->addHours(200),
[ 'id' => $user->id ]
);
我已确保
APP_KEY
已设置。我不太确定应该采取什么步骤来解决这个问题。我正在使用 Laravel Forge 进行部署。我还使用负载均衡器,但只有一个应用程序服务器 atm。
为什么
在生产中抛出temporarySignedRoute()
?InvalidSignatureException
编辑:
记录请求,我得到以下数据:
// [ $expired, $url, $query, $original, $signature ]
[
false,
"http://xx.xx/activate/13",{"expires":"1537076308","signature":"9d972a574137bf7e5f30120c3f539a81bca71875020c3476e3bfb230220a73f7"},
"http://xx.xx/activate/13?expires=1537076308",
"ed80a6ae717e806fd5f887224c2ac88f5fffb893ae284cc52688ba0690d3a9e1"
]
请注意,URL 以
http://
开头,但实际生成的链接使用 https://
。 URL 用 request()->url()
记录。这让我相信问题出在 http-scheme 上。
在我的
AppServiceProvider.php
中,我强制使用这样的https:
if (env('APP_ENV') == 'production') {
\URL::forceScheme('https');
}
为什么
request()
收到的信息是非 http 的?
这是由于我的负载均衡器未向服务器发送 HTTPS 调用造成的。这意味着服务器正在散列与原始 (https) 不同的 URL 方案 (http)。
我遇到了同样的问题,Fredrik 的回答很有帮助。
当我在生成签名 URL 时转储请求时,我发现我的服务器正在从“http”而不是“https”请求,即使该网站是通过“https”提供服务的。我必须更改我的 Cloudflare 设置以在请求上强制使用 https...
在 laravel 11 中需要添加 TrustProxies,因此我在其中创建了中间件 应用程序/Http/Middleware/SetTrustedProxies.php
命名空间 App\Http\Middleware;
使用 Illuminate\Http\Middleware\TrustProxies 作为中间件; 使用 Symfony\Component\HttpFoundation\Request 作为 SymfonyRequest;
SetTrustedProxies 类扩展了中间件 {
protected $proxies = '*';
protected $headers = SymfonyRequest::HEADER_X_FORWARDED_FOR |
SymfonyRequest::HEADER_X_FORWARDED_PROTO |
SymfonyRequest::HEADER_X_FORWARDED_HOST;
}
然后在 bootstrap/app.php 中添加这个中间件 使用 App\Http\Middleware\SetTrustedProxies;
->withMiddleware(函数 (中间件 $middleware) { $middleware->web(附加: [ 设置区域设置::类, ]); $middleware->append(SetTrustedProxies::class); })
此后它开始投入生产