Skip to content

twilio.webhook() returning unauthorized although TWILIO_AUTH_TOKEN is set #1080

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

Open
gborobio73 opened this issue Mar 24, 2025 · 2 comments
Open
Labels
status: waiting for feedback waiting for feedback from the submitter type: bug bug in the library

Comments

@gborobio73
Copy link

Hello, we are using the twilio.webhook() as described in here
https://www.twilio.com/docs/usage/tutorials/how-to-secure-your-express-app-by-validating-incoming-twilio-requests#use-twilio-express-request-validation-middleware.

The code we are running is exactly like this:

// index.ts 
import express, { Request, Response } from 'express';
import twilio from 'twilio';
import bodyParser from 'body-parser';
import VoiceResponse from 'twilio/lib/twiml/VoiceResponse';
import MessagingResponse from 'twilio/lib/twiml/MessagingResponse';

const shouldValidate = process.env.NODE_ENV !== 'test';
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));

app.post('/api/call', twilio.webhook({ validate: shouldValidate }), (req: Request, res: Response) => {
  // Twilio Voice URL - receives incoming calls from Twilio
  console.log('Call received; greeting the caller');
  const response = new VoiceResponse();

  response.say(
    `Thanks for calling!
     Your phone number is ${req.body.From}. I got your call because of Twilio´s
     webhook. Goodbye!`
  );

  res.set('Content-Type', 'text/xml');
  res.send(response.toString());
});

app.post(
  '/message',
  twilio.webhook({ validate: shouldValidate }),
  (req: Request, res: Response) => {
    // Twilio Messaging URL - receives incoming messages from Twilio
    const response = new MessagingResponse();

    response.message(`Your text to me was ${req.body.Body
      .length} characters long.
                    Webhooks are neat :)`);

    res.set('Content-Type', 'text/xml');
    res.send(response.toString());
  }
);
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});

But we can see in the logs that the call results in unauthorized:

2025-03-24T15:06:05.720895+00:00: at=info method=POST path="/api/call" host= request_id= fwd="" service=3ms status=403 bytes=241 protocol=https

The TWILIO_AUTH_TOKEN is set, and it's the one from the Twilio console.

Is there anything else that we are missing?

Thank you!

@gborobio73
Copy link
Author

But, this approach works https://www.twilio.com/en-us/blog/how-to-secure-twilio-webhook-urls-in-nodejs using exactly the same code.

@kevinburke
Copy link

It's good you narrowed this down to a working code version vs. one that's not working.

If you can edit the twilio-node code inside your node_modules directory - could you verify that twilio.validateRequest is being called with the same arguments in both cases? In the blog post demo, it's being called with a protocol and host that I'm not sure you are getting from your Express app.

@tiwarishubham635 tiwarishubham635 added type: bug bug in the library status: waiting for feedback waiting for feedback from the submitter labels Apr 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting for feedback waiting for feedback from the submitter type: bug bug in the library
Projects
None yet
Development

No branches or pull requests

3 participants