Posted at

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

More than 3 years have passed since last update.


特定の 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


参考