Railsでset-cookieを止める方法

プログラミング、サーバー、ネットワーク、IT用語、ハマったときのトラブルシューティングなど様々なIT関連の話題をひたすら書いていく技術ブログです。

2017年2月2日木曜日

Railsでset-cookieを止める方法


Ruby On Railsでは毎回デフォルトでset-cookieをレスポンスヘッダーに追加してレスポンスが返ってきます。これを知らなかったために管理画面の配下で画面遷移しようとするとなぜかセッションが切れてログアウト状態になっていたのでそれを回避するための方法です。

Nginxキャッシュを設定したらバグり始めた

なぜset-cookieを止める事態になったかというと、Nginxでキャッシュを生成し始めたからです。Railsが毎リクエストの度にset-cookieをしていることを知りませんでした。それがどうかバグったのかというと、1度目のリクエスト時はキャッシュがないのでRailsのプログラムが起動してset-cookieを含めてレスポンスしてきます。それをNginxは感知してset-cookieを含めてキャッシュとしてバイナリファイルを生成してクライアント側へレスポンスを返します。

2回目にアクセスするときは当然キャッシュは存在しているのでRailsのプログラムは走りません。なのでcookieはキャッシュに含まれているset-cookieで毎回上書きされます。webサイト上にはキャッシュされたいページとさせたくないページが存在することも多いと思います。例えば情報を入力する管理ページなどはキャッシュされたくないはずです。私の場合、今までどのページでも基本的に毎リクエストの度にRailsが回って返してくるので整合性が取れていました。しかし、キャッシュがある状態で毎回set-cookieされる管理画面から、ユーザーが見るキャッシュされているページを見ると、先ほど生成したキャッシュに含まれた古いキャッシュで返ってくるので、cookieが古いIDで上書きされます。そうなるとクライアント側で持っているcookieとその時点でRailsが正としているcookieが違うため、管理画面などにログインしている場合はセッションが切れてログアウトした状態になりました。

set-cookieを飛ばさないで、キャッシュのset-cookieを正とする解決法

これを解決するために下記のようにします。

before_action :hoge
.
.
.

def hoge
request.session_options[:skip] = true
end

session_optionの[:skip]をtrueにすると該当するページはset-cookieが送られません。そうすればキャッシュされたページは常にそのキャッシュの中のcookieで対応できるため、バグることがなくなりました。なかなか気付くことが難しいですね。因みにNginx側でもset-cookieを返さないといったディレクティブが存在してるので、そちらもいつか試してみたいと思います。

◯Ruby on Railsの記事一覧はこちら
◯トラブルの解決方法の一覧はこちら



最近の投稿