Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gRPC interceptor #102

Open
p-stoyanov opened this issue Mar 16, 2023 · 1 comment
Open

gRPC interceptor #102

p-stoyanov opened this issue Mar 16, 2023 · 1 comment

Comments

@p-stoyanov
Copy link

p-stoyanov commented Mar 16, 2023

Hello, I have a grpc service and I want to implement JWT token authentication, for now, I just need to validate that the token is valid. With http this is possible via Symfony authenticator or middleware but with grpc request it doesn't work. As far as I understand, with grpc, this can be achieved through an interceptor, which is an analog of http middleware. Is there a way to implement similar functionality through this bundle?

@p-stoyanov p-stoyanov changed the title gRPC JWT authentication gRPC interceptor Mar 16, 2023
@genhoi
Copy link

genhoi commented May 11, 2023

@p-stoyanov You can do this through your implementation of the Spiral\RoadRunner\GRPC\InvokerInterface and replace the service with your implementation with the id Spiral\RoadRunner\GRPC\Invoker

For example, like this:
services.yaml

    Spiral\RoadRunner\GRPC\Invoker:
        class: App\Infrastructure\Grpc\Roadrunner\Invoker

InvokerInterface implementation

<?php

declare(strict_types=1);

namespace App\Infrastructure\Grpc\Roadrunner;

use Google\Protobuf\Internal\Message;
use Spiral\RoadRunner\GRPC\ContextInterface;
use Spiral\RoadRunner\GRPC\Exception\InvokeException;
use Spiral\RoadRunner\GRPC\InvokerInterface;
use Spiral\RoadRunner\GRPC\Method;
use Spiral\RoadRunner\GRPC\ServiceInterface;
use Spiral\RoadRunner\GRPC\StatusCode;
use Throwable;

class Invoker implements InvokerInterface
{

    /**
     * {@inheritDoc}
     */
    public function invoke(ServiceInterface $service, Method $method, ContextInterface $ctx, ?string $input): string
    {
        /** @var callable $callable */
        $callable = [$service, $method->getName()];

        $arg = $this->makeInput($method, $input);

        // A place to implement the middleware template
        $message = $callable($ctx, $arg);;

        try {
            $message = $message->serializeToString();

            return $message;
        } catch (Throwable $e) {
            throw InvokeException::create($e->getMessage(), StatusCode::INTERNAL, $e);
        }
    }

    /**
     * @throws InvokeException
     */
    private function makeInput(Method $method, ?string $body): Message
    {
        try {
            $class = $method->getInputType();

            /** @psalm-suppress UnsafeInstantiation */
            $in = new $class();

            if (null !== $body) {
                $in->mergeFromString($body);
            }

            return $in;
        } catch (Throwable $e) {
            throw InvokeException::create($e->getMessage(), StatusCode::INTERNAL, $e);
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants