1

Symfony 5.3.10

PHP 8.0.8

I have a public webhook used for user activation (by clicking a link in an email).

Something like: https://mydomain.fake/user/123-5346-6787-89-789/1234678567945asd

The activation is performed by an api request, so i need to generate a subrequest inside the controller of the webhook

#[Route('/activate/{uuid}/{token}', name: 'webhook.user_settings')]
    public function index(string $uuid, string $token, Request $request, HttpKernelInterface $httpKernel): Response
    {

        $url = sprintf($request->getSchemeAndHttpHost() . "/api/user/%s/activate?token=%s",
            $uuid,
            $token
        );

        $request = Request::create($url, 'PATCH', [], [], [], [], json_encode([], \JSON_THROW_ON_ERROR));
        $request->setMethod('PATCH');
        $request->headers->set('Content-Type', 'application/merge-patch+json');

        $result = $httpKernel->handle($request, HttpKernelInterface::SUB_REQUEST);

        if ($result->getStatusCode() === Response::HTTP_OK) {
            $user = json_decode($result->getContent());
            $body = "<html><body><h2>Complimenti '" . $user->name . "', attivazione avvenuta con successo</h2></body></html>";
        } else {
            $body = "<html><body><h2>Ooops! Qualcosa è andato storto</h2></body></html>";
        }
        return new Response($body, $result->getStatusCode());
    }

It worked until today (i've tested last time some week ago but it worked fine for months)

Now the request to the api is performed, the user activated but the $result is in state 400

Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\BadRequestHttpException: "There is currently no session available."

If i call the api directly (using Postman) it works as expected.

Where am i wrong?

Jack Skeletron
  • 1,351
  • 13
  • 37
  • Why do you need a subrequest for this? Why not refactor the action that the subrequest performs to a proper service which you could also call from this route? – Nico Haase Nov 04 '21 at 15:03
  • Because i don't have a proper web app to handle this yet, and this is the fastest way to perform all the related actions (log, events, etc.) – Jack Skeletron Nov 04 '21 at 16:08
  • Dont't know who but the downvote without any reason is the silliest of the actions. – Jack Skeletron Nov 05 '21 at 09:30
  • I see you found a solution but I'm still not sure this is a valid use of sub requests. Seems like you should use the [HttpClient](https://symfony.com/doc/current/http_client.html) service to access the api. Though I suppose it might have to do with your session stuff. Also a bit surprised that someone with 1K+ rep does not know that drive by downvotes are recommended on stackoverflow. – Cerad Nov 05 '21 at 13:58

1 Answers1

2

Solved by adding the session of the main request to the subrequest

public function index(string $uuid, string $token, Request $request, HttpKernelInterface $httpKernel): Response
    {

        $url = sprintf($request->getSchemeAndHttpHost() . "/api/user/%s/activate?token=%s",
            $uuid,
            $token
        );
        $session = $request->getSession();
        $request = Request::create($url, 'PATCH', [], [], [], [], json_encode([], \JSON_THROW_ON_ERROR));
        $request->setMethod('PATCH');
        $request->headers->set('Content-Type', 'application/merge-patch+json');
        $request->setSession($session);

        $result = $httpKernel->handle($request, HttpKernelInterface::SUB_REQUEST);

        if ($result->getStatusCode() === Response::HTTP_OK) {
            $user = json_decode($result->getContent());
            $body = "<html><body><h2>Complimenti '" . $user->name . "', attivazione avvenuta con successo</h2></body></html>";
        } else {
            $body = "<html><body><h2>Ooops! Qualcosa è andato storto</h2></body></html>";
        }
        return new Response($body, $result->getStatusCode());
    }
Jack Skeletron
  • 1,351
  • 13
  • 37