Search code examples
twiliotwilio-apitwilio-phptwilio-twiml

Webhook not valid after <Redirect> in Twilio


I am trying to test a workflow in twilio, the workflow is like this:

  • A call comes in and my server gets hit by twilio, the request is valid per the docs
  • The webhook returns a Twiml with a Redirect to another endpoint in order to enqueue the call.
  • On this endpoint the webhook is invalid.

All endpoints except for this second endpoint are being validated correctly. Is there any special case I need to account for when validating redirects like this?

I am using laravel if that matters.

[Edit1]

The twiml looks like this

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say></Say>
    <Redirect>https://example.com/webhook/call/handle-incoming-call?Enqueue=1</Redirect>
</Response>

After making the redirection to that url the request returns a 403 error.

For validation, I am using the following code in a middleware for the routes in laravel.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Response;
use Twilio\Security\RequestValidator;

class TwilioRequestValidator
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Be sure TWILIO_TOKEN is set in your .env file.
        // You can get your authentication token in your twilio console https://www.twilio.com/console
        $requestValidator = new RequestValidator(env('TWILIO_TOKEN'));

        $requestData = $request->toArray();

        // Switch to the body content if this is a JSON request.
        if (array_key_exists('bodySHA256', $requestData)) {
            $requestData = $request->getContent();
        }
        $isValid = false;

        if ($request->hasHeader('X-Twilio-Signature')) {
            $isValid = $requestValidator->validate(
                $request->header('X-Twilio-Signature'),
                $request->fullUrl(),
                $requestData
            );
        }


        if ($isValid) {
            return $next($request);
        } else {
            return new Response('Invalid Request', 403);
        }
    }
}

Thanks.


Solution

  • Twilio developer evangelist here.

    Rather than using request->toArray() which returns all the parameters, you just need the body parameters. The query string parameters are already dealt with in the request->fullUrl().

    Try request->post() to get the POST data instead.