当前位置: 首页 > 知识库问答 >
问题:

Laravel 5.7签名路由返回403无效签名

潘飞英
2023-03-14

我试图利用Laravel5.7中新的签名中间件,但由于某些原因,生成的签名URL返回403个无效签名。

我使用最新的Laravel版本,PHP 7.2

这是我的web.php路线:

Route::get('/report/{user}/{client}', function ($user, $client) {
    return ("El usuario es: $user y el cliente es: $client");
})->name('report.client')->middleware('signed');

这是在我的控制器:

$objDemo->tempURL = Url::temporarySignedRoute('report.client', now('America/Panama')->addDays(5), [
            'user' => 1,
            'client' => 1
        ]);

生成URL并显示如下内容:

https://example.com/report/1/1?expires=1545440368

但是,当我点击链接时,结果是403,并显示消息:“无效签名”

有什么想法吗?提前谢谢

-----------更新------------

我已经做过的事情:

  1. 在没有签名的情况下尝试这条路线,效果很好

似乎什么都不起作用,总是得到403无效的签名页

-----------更新2------------

好的,在一些挖掘和测试之后,我发现如果用户登录,laravel签名的路由将不起作用,这很奇怪,如果我注销,则路由工作正常,但如果我登录,则显示403错误,这可能是因为laravel在所有其他操作之后添加了会话cookie头?所以签名路由就因为它而失败了?是这样吗?

奇怪的是,假设我想为我的用户创建一个临时链接来下载一些东西,如果他们登录到我的Laravel应用程序,他们会收到403错误消息…:(

------------更新3------------------

我尝试了laravel的新安装,并且工作得很好,所以这是我的主要Laravel应用程序的东西,也尝试将每个作曲家依赖项安装到Laravel的新安装中,并且无论用户登录状态如何,仍然工作得很好,所以它与我的依赖。

共有3个答案

颜志学
2023-03-14

我只是有这个问题,原来URL中的空参数永远不会验证。所以当你这样做的时候:

URL::temporarySignedRoute('newsletter.verify', now()->addDays(3), ['name' => $name, 'email' => $email])

但name是一个空字符串(因为它不是强制性的),URL将以name=作为查询字符串的一部分生成,但此代码位于Laravel中

$original = rtrim($url.'?'.Arr::query(Arr::except($request->query(), 'signature')), '?');

不会返回空的名称,因此URL已“更改”,验证失败。常用的中间件convertEmptyStringsToull可能与此有关。

贺聪
2023-03-14

请尝试以下代码:

class TrustProxies extends Middleware
{
    protected $proxies = '*';
    protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
白子昂
2023-03-14

调试UrlGenerator::hasValidSignature()后,我通过DD结束了UrlGenerator.php中的变量,如下所示:

public function hasValidSignature(Request $request, $absolute = true)
    {
        $url = $absolute ? $request->url() : '/'.$request->path();

        //dd($url);

        $original = rtrim($url.'?'.Arr::query(
            Arr::except($request->query(), 'signature')
        ), '?');

        dd($original);
        $expires = Arr::get($request->query(), 'expires');

        $signature = hash_hmac('sha256', $original, call_user_func($this->keyResolver));

        return  hash_equals($signature, (string) $request->query('signature', '')) &&
               ! ($expires && Carbon::now()->getTimestamp() > $expires);
    }

$原始变量向我展示了我的URL实际上发生了什么,并显示了以下内容:

https://example.com/report/1/1?expires=1546586977&settings%5Bincrementing%5D=1&settings%5Bexists%5D=1&settings%5BwasRecentlyCreated%5D=0&settings%5Btimestamps%5D=1&profile%5Bincrementing%5D=1&profile%5Bexists%5D=1&profile%5BwasRecentlyCreated%5D=0&profile%5Btimestamps%5D=1&user%5Bincrementing%5D=1&user%5Bexists%5D=1&user%5BwasRecentlyCreated%5D=0&user%5Btimestamps%5D=1

正如您可以看到的,expires参数之后有一些参数,这些参数在路由创建之后被删除,这就是问题所在,之所以发生这种情况,是因为我有一个中间件,它将一些信息共享给视图,如下所示:

UserDataMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use App\User;
use App\Setting;
use App\UserProfile;
use Illuminate\Support\Facades\View;

class UserData
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        if (Auth::check()) {
            $settings = Setting::where('user_id', Auth::user()->id)->first();
            $profile = UserProfile::where('user_id', Auth::id())->first();
            $user = Auth::user();

            View::share('settings', $settings); //Another way to share variables, with the View::share
            View::share('profile', $profile);

            //Now we need to share owr variables trough the REQUEST to our controllers
            $request->merge([
                'settings' => $settings,
                'profile' => $profile,
                'user' => $user
            ]);


        }
        return $next($request);
    }
}

这个中间件在中间件组中,所以这是一个问题,希望如果将来有人实验这个,那么它可以首先检查这个。

 类似资料:
  • PDF创建步骤: 通过添加空签名字段名称创建pdf:suhasb@gmail.com和nikhil.courser@gmail.com,使用原始的hello.pdf输出文件名hello_tag.pdf运行程序>tagpdfsignaturefields.java 从hello_tag.pdf文件中提取签名字段suhasb@gmail.com进行首次签名,输出文件名为hello_signd.pdf

  • 使用curl或postman,我得到403禁止: Lambda函数具有以下权限: S3桶具有以下CORS规则:

  • 我怀疑问题是路径包含a:这在Windows上是非法的。 研究错误后,我找到了2个可能的答案: 1)更改存储库文件的路径。不幸的是,这是一个团队资源,在可预见的将来无法修复。 2)使用稀疏签出。我尝试过这种方法但没有效果,如下所示: $git克隆-n git@github.com:xxxxx/deploy.git 克隆到“deploy”... 远程:枚举对象:57,完成。 远程:计算对象:100%(

  • 我正在尝试从外部远程服务对文档进行签名。签署过程分两个阶段进行。远程服务在第一阶段期待base64编码的散列,并在身份验证后发出令牌。在第二阶段,我们将使用接收到的令牌再次传递相同的散列并获得base64签名的散列。我在这里附上签名错误的文件。文件 如果有人可以分析它并指导我评估无效签名背后的原因。我正在使用执行与pdf相关的操作。 更新 根据反馈,我做了一些更正。文档现在正在更改。已更改的文档

  • 我正在使用nginx和react。我的nginx.conf文件 根据此配置,nginx为所有路由服务200。假设我的路线是 现在假设有人输入错误的url 在这种情况下,我想抛出404而不落地到nginx级别本身的应用程序。这是否可能在nginx级别处理路由和发送404尽管200和比在REACTE级别处理。 我发现要在nginx级别限制任何特定的路由,我们可以使用下面的代码来实现 但我想限制所有对我

  • 我正在尝试手动创建ES256 JWT令牌。我有一个用python编写的小脚本,它对使用ecdsa python的sha256哈希进行签名。但签名在jwt上无效。木卫一。 繁殖步骤: 创建Base64报头负载: eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9。EYJZDWIixMJ0Nty3ODKwiiBmFtzSi6IkPvAg4GrG9LiiWiyWrTaw4Ionry