LoginSignup
6
3

More than 5 years have passed since last update.

Rails 3.x で API がうまく動いていないのを調査したきの話

Posted at

特定の API がうまく動いていない?

調査したのはシンプルな API を提供するアプリで

  1. 認証 API を実行:セッションに認証済みの情報をセット
  2. 各種 API を実行:セッションを検証し、認証済みの場合のみ実行可

という仕組みのものでした。で、なぜか特定の API だけ認証済みでもエラーとなるので調査してちょうだいということでした。

エラー内容は「認証されてないよ」

その API からは「認証されてないよ」という旨のエラーが返却されていました。
なぜ?と思って調べを進めてみると、どうやらその API にアクセスする度に新しいセッションが生成されていて、認証済みの情報が消えているためだということが分かりました。

ログに「Can't verify CSRF token authenticity」

他の API との違いはなんだろう?と思いつつログとにらめっこ。
よく見るとうまく動いていない API を叩いた場合のみ「Can't verify CSRF token authenticity」が発生していました。ということは・・・

原因は reset_session

先のログは protect_from_forgery で NG の場合に出力されます。で、その後 reset_session されているためセッションが再生成されていたようでした。

application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery

request_forgery_protection.rb
def protect_from_forgery(options = {})
  self.request_forgery_protection_token ||= :authenticity_token
  prepend_before_filter :verify_authenticity_token, options  # <-- (1)
end

def verify_authenticity_token
  unless verified_request?
    logger.warn "WARNING: Can't verify CSRF token authenticity" if logger
    handle_unverified_request # <-- (2)
  end
end

def handle_unverified_request
  reset_session # <-- (3) ここでセッションがリセットされる
end

verify_authenticity_token をスキップして解決

protect_from_forgery はシステムを堅牢にしてくれる仕組みなので重宝しますが、今回のように外部に公開する API には不要なので、その処理が走らないようにスキップしておきましょう。

hoge_controller.rb
class HogeController < ApplicationController
  skip_before_filter :verify_authenticity_token
end

参考

6
3
0

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
6
3