LoginSignup
5

More than 5 years have passed since last update.

[Rails][Twilio]バリデーションリクエストを使う

Last updated at Posted at 2016-01-15

Twilioからのバリデーションリクエスト

要するに以下の様なときに使うやつです。

(サーバが)受け取るHTTPリクエストが確かにTwilioからのものであり、不審な第三者からのものではないことを確実にしたい

詳細はTwilioドキュメントを御覧ください。

やり方

routes.rb を設定する

twilioからのリクエストを受けるルートは、何か適当なnamespaceをつけるのをオススメします。

config/routes.rb
Rails.application.routes.draw do
  namespace :phone do
    post 'incoming', to: 'incoming#new', format: true
  end
end

configを設定する

configにtwilioのAPIを使うためのキーを設定します。
(実際はソース上に直に書いたりはしないと思います)

config/initializers/twilio.rb
Twilio.configure do |config|
  config.account_sid = 'account_sid'
  config.auth_token  = 'auth_token'
end

application_controller.rb を書く

Twilio用のapplication_controller.rbを作成します。ここでvalidationをします。

app/controllers/phone/application_controller.rb
class Phone::ApplicationController < ApplicationController
  protect_from_forgery with: :null_session
  before_action :validate_incoming_requests, if: -> { !(Rails.env.test? || Rails.env.development?) }

  RequestValidationError = Class.new(StandardError)
  rescue_from RequestValidationError, with: :handle_401

  private

  def validate_incoming_requests
    return unless request.post?
    validator = Twilio::Util::RequestValidator.new
    signature = request.headers['X-Twilio-Signature']
    fail RequestValidationError unless validator.validate(request.url, request.request_parameters, signature)
  end

  def handle_401
    render xml: reject_twiml, status: 401
  end

  def reject_twiml
    Twilio::TwiML::Response.new do |r|
      r.Reject reason: :busy
    end.text
  end
end

Controller.rb を書く

ここではvalidationを意識する必要は有りません。
Twilio用のapplication_controller.rbを継承するのをお忘れなく。

app/controllers/phone/incoming_controller.rb
class Phone::IncomingController < Phone::ApplicationController
  def new
  # 本当はpostらしい処理を書く
    render xml: say_twiml
  end

  private

  def say_twiml
    Twilio::TwiML::Response.new do |r|
      r.Say 'It is fine today.'
    end.text
  end
end

注意点

namespaceに"twilio"を使わない

その名前はtwilio-rubyジェムで使われています。問題ないとは思いますが、避けるに越したことは有りません。また、大抵の場合はもっとアプリケーションに適した名前があります。

バリデーションの際にrequest.paramsを使わない

request.paramsを使うとvalidationが失敗します。request.paramsにはrailsで追加したcontrolleractionなどが含まれているからです。
なので、上記のソースではrequest.request_parametersを使用しています。これはrailsで追加した値は含みません。

参考

Railsのparamsからcontrollerとかpathに関係するパラメータを除きたい
Validate Incoming Requests - twilio-ruby

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5