【问题标题】:Create a signedRoute in laravel Lumen API在 laravel Lumen API 中创建签名路由
【发布时间】:2020-08-12 21:09:45
【问题描述】:

在 laravel Lumen 中使用来自 URL 外观的 signedRoute 时出现错误

Call to undefined method Laravel\Lumen\Routing\UrlGenerator::signedRoute()

当我检查 URLGenerator 类时,我可以看到函数在那里。是不是我做错了什么?

【问题讨论】:

  • 我一直在寻找同样的东西。经过一番挖掘,似乎 UrlGenerator Facade 在类的 DocBlock 中有方法,但 \Illuminate\Routing\UrlGenerator 在 Lumen 框架中不存在。确实进入 Lumen 的类根本没有对“签名”路由的任何引用。我想搜索还在继续……

标签: laravel api url lumen


【解决方案1】:

普通的 Lumen 是不可能的。这些函数根本不会出现在source 中,即使外观的 DocBlock 另有说明。

一种选择是将 Laravel 框架源 (/src/Illuminate/Routing/UrlGenerator.php#L308-L411) 中的函数提取到您自己的 UrlGenerator 类中并绑定它:

应用\服务\UrlGenerator:

class UrlGenerator extends \Laravel\Lumen\Routing\UrlGenerator
{
    use InteractsWithTime;

    /**
     * The encryption key resolver callable.
     *
     * @var callable
     */
    protected $keyResolver;

    /**
     * Create a signed route URL for a named route.
     *
     * @param  string  $name
     * @param  mixed  $parameters
     * @param  \DateTimeInterface|\DateInterval|int|null  $expiration
     * @param  bool  $absolute
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    public function signedRoute($name, $parameters = [], $expiration = null, $absolute = true)
    {
        $parameters = Arr::wrap($parameters);

        if (array_key_exists('signature', $parameters)) {
            throw new InvalidArgumentException(
                '"Signature" is a reserved parameter when generating signed routes. Please rename your route parameter.'
            );
        }

        if ($expiration) {
            $parameters = $parameters + ['expires' => $this->availableAt($expiration)];
        }

        ksort($parameters);

        $key = call_user_func($this->keyResolver);

        return $this->route($name, $parameters + [
                'signature' => hash_hmac('sha256', $this->route($name, $parameters, $absolute), $key),
            ], $absolute);
    }

    /**
     * Create a temporary signed route URL for a named route.
     *
     * @param  string  $name
     * @param  \DateTimeInterface|\DateInterval|int  $expiration
     * @param  array  $parameters
     * @param  bool  $absolute
     * @return string
     */
    public function temporarySignedRoute($name, $expiration, $parameters = [], $absolute = true)
    {
        return $this->signedRoute($name, $parameters, $expiration, $absolute);
    }

    /**
     * Determine if the given request has a valid signature.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  bool  $absolute
     * @return bool
     */
    public function hasValidSignature(Request $request, $absolute = true)
    {
        return $this->hasCorrectSignature($request, $absolute)
            && $this->signatureHasNotExpired($request);
    }

    /**
     * Determine if the given request has a valid signature for a relative URL.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    public function hasValidRelativeSignature(Request $request)
    {
        return $this->hasValidSignature($request, false);
    }

    /**
     * Determine if the signature from the given request matches the URL.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  bool  $absolute
     * @return bool
     */
    public function hasCorrectSignature(Request $request, $absolute = true)
    {
        $url = $absolute ? $request->url() : '/'.$request->path();

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

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

        return hash_equals($signature, (string) $request->query('signature', ''));
    }

    /**
     * Determine if the expires timestamp from the given request is not from the past.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    public function signatureHasNotExpired(Request $request)
    {
        $expires = $request->query('expires');

        return ! ($expires && Carbon::now()->getTimestamp() > $expires);
    }

    /**
     * Set the encryption key resolver.
     *
     * @param  callable  $keyResolver
     * @return $this
     */
    public function setKeyResolver(callable $keyResolver)
    {
        $this->keyResolver = $keyResolver;

        return $this;
    }
}

App\Providers\AppServiceProvider:

$this->app->bind(\App\Services\UrlGenerator::class, function () {
    $urlGeneratorWithSignedRoutes = new \App\Services\UrlGenerator($this->app);

    $urlGeneratorWithSignedRoutes->setKeyResolver(function () {
        return $this->app->make('config')->get('app.key');
    });

    return $urlGeneratorWithSignedRoutes;
});

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 2019-07-17
    • 1970-01-01
    • 2017-07-28
    • 2016-05-16
    • 2020-11-10
    • 2020-07-17
    • 2016-07-06
    • 2019-12-12
    相关资源
    最近更新 更多