RamJet
RamJet

Reputation: 303

Twilio authentication fails in rails 4

I have a method to authenticate my phone call is coming from Twilio. It's a cut and paste from various examples I found on the net some time ago. I get the following message,

Filter chain halted as :authenticate_twilio_request rendered or redirected
Completed 401 Unauthorized in 4ms (Views: 1.0ms | ActiveRecord: 0.0ms)

Ok. It's failing validation. When I first started playing with Twilio, I used this method in my "proof of concept" design phase. It wasn't failing at that time, (although, I don't know if it was working either). I've just added it back in now that I've finished my phone controller.

  def authenticate_twilio_request
    logger.debug '+ authenticate_twilio_request()' if COMMS_DEBUG
    twilio_signature = request.headers['HTTP_X_TWILIO_SIGNATURE']
    @validator = Twilio::Util::RequestValidator.new(
      Rails.application.secrets.twilio_token
    )
    # the POST variables attached to the request (eg "From", "To")
    # Twilio requests only accept lowercase letters. So scrub here:
    post_vars = params.reject {|k, v| k.downcase == k}

    logger.debug '* post_vars = ' + post_vars.to_s if COMMS_DEBUG
    logger.debug '* request.url = ' + request.url if COMMS_DEBUG
    logger.debug '* twilio_signature = ' + twilio_signature if COMMS_DEBUG

    is_twilio_req = @validator.validate(
      request.url, post_vars, twilio_signature
    )
    unless is_twilio_req
      render :xml => (Twilio::TwiML::Response.new {|r| r.Hangup}).text,
        :status => :unauthorized
      false
    end
  end

The request.url that I've printed with logger.debug, seems to have extra data tacked on after the URL. Please see below.

* request.url = https://????????.ngrok.io/questions/1788?Called=%2B61294768366&ToState=Sydney&CallerCountry=AU&Direction=outbound-api&CallerState=Parramatta&ToZip=&CallSi
d=CA5e94751c4a7f9080ebcb8b78f71afe58&To=%2B61294768366&CallerZip=&ToCountry=AU&ApiVersion=2010-04-01&CalledZip=&CalledCity=&CallStatus=in-progress&From=%2B61288800922&Acc
ountSid=AC08bce5d0e2986f06e6105695caa83fcd&CalledCountry=AU&CallerCity=&Caller=%2B61288800922&FromCountry=AU&ToCity=&FromCity=&CalledState=Sydney&FromZip=&FromState=Parra
matta

The other logger.debug data appears correct. Is that the problem? If it is how do I fix it? If not, what's wrong?

Upvotes: 0

Views: 160

Answers (1)

philnash
philnash

Reputation: 73027

Twilio developer evangelist here (yes, I found this in the end!).

I can actually recommend that writing this code is unnecessary. A while back I wrote a rack middleware that can handle authenticating that requests come from Twilio.

To implement this with Rails you just need to add the middleware to your Rails config:

Rails.application.configure do
  # Other Rails config

  config.middleware.use Rack::TwilioWebhookAuthentication, Rails.application.secrets.twilio_token, '/messages'
end

The final argument is a path, or list of paths, that you want to validate come from Twilio. You can pass strings or regexps.

Give that a go and let me know if it works.

Upvotes: 2

Related Questions