Laravel 签名路由在生产中抛出 InvalidSignatureException

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

每当我在

生产
上访问使用 temporarySignedRoute() 创建的 URL 时,它都会抛出
InvalidSignatureException
。但是,在 dev 环境中,它可以工作。我也尝试过使用
signedRoute()
但没有成功。

我正在创建这样的网址:

\URL::temporarySignedRoute(
    'user.activate', 
    now()->addHours(200), 
    [ 'id' => $user->id ]
);

网址示例:https://xx.xx/activate/5?expires=1537065074&signature=f57713b2fccea5ce17b7c1a3241e275d62f1994cd8004ea480cced2402081090

我已确保

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 的?

php laravel
3个回答
1
投票

这是由于我的负载均衡器未向服务器发送 HTTPS 调用造成的。这意味着服务器正在散列与原始 (https) 不同的 URL 方案 (http)。


0
投票

我遇到了同样的问题,Fredrik 的回答很有帮助。

当我在生成签名 URL 时转储请求时,我发现我的服务器正在从“http”而不是“https”请求,即使该网站是通过“https”提供服务的。我必须更改我的 Cloudflare 设置以在请求上强制使用 https...


0
投票
  1. 首先在服务站点添加
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  • proxy_set_header X-Forwarded-Proto $scheme;
  1. 在 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;

}

  1. 然后在 bootstrap/app.php 中添加这个中间件 使用 App\Http\Middleware\SetTrustedProxies;

    ->withMiddleware(函数 (中间件 $middleware) { $middleware->web(附加: [ 设置区域设置::类, ]); $middleware->append(SetTrustedProxies::class); })

此后它开始投入生产

© www.soinside.com 2019 - 2024. All rights reserved.