はじめに
こんにちは。アメリカで独学でエンジニアを目指している者です。
以前の記事ではセッションについて取り上げましたが、Railsに関する記事はまだ執筆していなかったため、今回はRailsにおけるセッションの役割や保存場所について解説します。
セッションとは?
Webアプリケーションでは、HTTPのリクエストとレスポンスは本来「ステートレス」(状態を持たない)通信であるため、ユーザーごとの状態を持続的に管理する仕組みとして セッション が利用されます。
セッションとは、ユーザーがWebアプリケーションにアクセスしてから離脱するまでの間、アプリケーション側がユーザーを特定して状態を保持する仕組みです。
Railsでは、このセッションに関わるデータを簡単に管理できるよう、コントローラー内で session というハッシュ形式のオブジェクト(例:session[:キー])を提供しています。
Railsにおけるセッションの役割
ユーザーのログイン状態管理
たとえば、session[:user_id]のようにユーザーのIDをセッションに保存することで、リクエストが増えても同じユーザーとして扱うことができます。ログインが成功すると、
session[:user_id] = user.id
各アクションで session[:user_id] を確認することで、ユーザーがログインしているかどうかを判定できます。
一時的なデータの保持
Railsチュートリアルでは扱っていませんが、ショッピングカートの情報や複数ページにまたがるフォームの入力内容など、一時的な情報をページ間で保持する際にもセッションが利用されます。
ただし、セッションはあくまで一時的なストレージであるため、大容量のデータを保存するのは推奨されません。
セッションの保存場所
Railsでは、セッションの「保存場所(ストア)」を切り替えることができます。
デフォルト設定はCookieStoreですが、他にもActiveRecord::SessionStoreやRedisなど、サーバーサイドで管理する方法も存在します。
CookieStore(デフォルト)
-
仕組み
RailsのデフォルトはCookieStoreで、セッションデータは暗号化・署名されたCookieとしてブラウザに保存されます。サーバー側にセッションデータを保管しないのが特徴です。Railsチュートリアルでもこの仕組みを採用しているはずです(8章まで)
-
CookieStoreのメリット
- セッション情報をサーバーが保持しないため、スケーリングが容易。
- レスポンスごとにサーバー側のストレージを介さないため、速度が速い。
-
CookieStoreのデメリット
- Cookieに保存できるデータ量に制限がある(通常4KB程度までが推奨)。
- データは署名・暗号化されているため改ざんは検出できるが、サイズが大きくなると通信量が増加。
サーバーサイドストア
Railsでは、CookieStore以外にもいくつか代表的なサーバーサイドストアがあります。
ActiveRecord::SessionStore
-
仕組み
セッション情報をデータベース(テーブル)に保存し、CookieにはセッションIDのみを保存します。
データベースを使うため、セッションデータの読み書きにはクエリが走ります。 -
メリット
- 大量のセッションデータを扱える。
- データベースを介しているので、Cookieの容量制限がなくなる。
- サーバー側でセッションを管理するため、セキュリティ面の制御がしやすい。
-
デメリット
- リクエストごとにDBへのアクセスが発生するため、負荷が増える可能性がある。
- データベースのマイグレーションが必要。
RedisやMemcachedなど
-
仕組み
セッションをインメモリデータストア(Redis、Memcachedなど)に保存し、CookieにはセッションIDのみを保存します。 -
メリット
- 低レイテンシで大量のセッションを扱える。
- 分散環境でも比較的スケールしやすい。
-
デメリット
- インメモリである分、データが揮発しうる(Redisでも永続化は可能だが設定が必要)。
- 追加のミドルウェアが必要。
Railsがセッションを生成するタイミング
意外に思われるかもしれませんが、Railsではログイン前でもセッションは存在します。
ユーザーがアプリケーションにアクセスした時点で、Railsはそのユーザー専用のセッションを作成し、CookieStoreであれば暗号化した空のCookieをブラウザに送信します。
ログイン時にsession[:user_id]を設定することで、セッションを活用してログイン状態を管理するのが一般的です。
セッションのリセットや有効期限
reset_sessionメソッド
ログアウト時などに呼び出すことで、セッションを初期化し、新しいセッションIDを発行します。
これにより、セッションフィクセーション攻撃を防ぎ、安全な新規セッションに切り替えることができます。
def log_out
reset_session
redirect_to root_url
end
Cookieの有効期限
これについてはまだ扱っていませんが、CookieStoreの場合は、config/initializers/session_store.rbでexpire_afterオプションを指定することで、Cookieの有効期限を設定できるようです
Rails.application.config.session_store :cookie_store, key: '_app_session', expire_after: 30.minutes
これを設定しない場合はブラウザのセッションCookieとして扱われ、ブラウザを閉じると削除されるのが一般的です。
まとめ
-
Railsのセッションは、
session[:キー]というハッシュ形式で、ユーザーごとの一時的な情報(ログインIDなど)を簡単に保持するための仕組み。 - CookieStore(デフォルト)では、暗号化・署名されたCookieにセッションデータが保存され、サーバー側にデータを持たないのが特徴。
- サーバーサイドストア(ActiveRecord、Redisなど)を利用する場合は、CookieにはセッションIDのみが入り、実際のデータはサーバーで管理する。
- ユーザーがアプリケーションにアクセスした時点で、匿名セッションが生成される。ログイン時に
session[:user_id]を登録することで、ログイン状態をセッションで管理する。 -
reset_sessionは、セッションを新しく生成し直すため、ログアウト処理やセキュリティ対策で重要な役割を担う。