DEVELOPER’s BLOG
技術ブログ
[AWS ECS + Rails] スティッキーセッションとCSRFトークンエラー対策
- はじめに
- スティッキーセッション(Sticky Session)とは
- Railsのセッション管理とCSRFトークン
- スティッキーセッションを無効化し、redisにセッションを保持させる場合
- 負荷分散とスティッキーセッションの設定 × セッションの保存場所
1. はじめに
AWS ECS上でRails on Railsで開発したWebアプリケーション(以下Railsアプリ)を運用する際、ユーザーごとのセッション管理は重要なポイントです。
負荷分散を行いたいのに、スティッキーセッションを無効にするとCSRF(クロスサイトリクエストフォージェリ)のトークンエラーが発生してしまうことがあります。「CSRFトークンエラーを避けるために、やむを得ずスティッキーセッションを有効にしている...」という状況になっていませんか?
この記事では、スティッキーセッションの設定とRailsセッションの保存場所の適切な組み合わせについて紹介します。
2. スティッキーセッション(Sticky Session)とは
AWSにおけるスティッキーセッションとは、ロードバランサー(ALB)が同じユーザーからのリクエストを常に同じサーバー(ECSタスク)へ振り分ける仕組みです。
ALBは独自に生成するCookieを用いてユーザーを識別し、前回接続したサーバーにリクエストを送ります。
ECサイトの購入フローのように、途中の入力内容を保持しておきたいステートフルなアプリや処理に便利です。
3. Railsのセッション管理とCSRFトークン
Railsではユーザーごとのセッション情報は、デフォルトでは Cookie に保存します。
またRailsはCSRF対策として、フォームに埋め込む CSRFトークン をセッションに保存し、次のリクエストで一致するか確認します。
ここで問題となるのが、スティッキーセッションを無効化した場合です。
ECSタスク間でリクエストが振り分けられると、リクエスト先のサーバーにセッションが存在せず、CSRFトークンが一致しなくなりエラーが発生します。
この問題を解決する方法が、RailsセッションをRedisなどの外部ストレージに置くことです。
Redisにセッションを保存することで、全てのサーバーが同じセッション情報を共有できるため、CSRFトークンエラーが解消されます。
4. スティッキーセッションを無効化し、redisにセッションを保持させる場合
Redisを使うためのgemを導入します。gem 'redis-actionpack'
config/initializers/session_store.rb に redisサーバーの設定を記載します。(ドキュメント参考)
5. 負荷分散とスティッキーセッションの設定 × セッションの保存場所
ECSタスクを複数台使ってアプリを運用しているとき、アプリの規模やステートフル/ステートレスかどうか、またはセキュリティ制約上セッション情報を保持する場所に制限があるかなどによって、負荷分散の必要性とそれに伴うセッション管理方式が決まります。
| スティッキーセッション | セッションの保存場所 | 負荷分散の効率 | 実装難易度 |
|---|---|---|---|
| 無効化 | Redis等の外部ストレージ | 高い | やや難しい (gem導入) |
| 有効化 | サーバーのメモリ/Cookie | 低い | 容易 (デフォルト設定) |
まとめると、システムの性質や要件に応じて次のように使い分けます:
ステートフルアプリや検証環境の場合
- スティッキーセッションを有効にする
- セッションをCookieに保存
ステートレスアプリや本番環境など安定運用を重視する場合
- 負荷分散のため、スティッキーセッションを無効にする
- セッションはRedisなどの外部ストレージに保存
これにより、CSRFトークンエラーを避けつつ、安定したアプリ運用が可能になります。
X(旧Twitter)・Facebookで定期的に情報発信しています!
Follow @acceluniverse