Railsのセッション情報はデフォルトでCookieに保存されます。
Railsのセッション管理方法は変更が可能で、Cookieの代わりにインメモリDBを採用するケースがよくあります。
今回はセッションの管理方法をCookieからインメモリDBであるRedisに変更する方法について紹介します。
目次
セッション管理をCookieからRedis(インメモリDB)に変えるメリット・デメリット
- Cookieで管理するデータ量が減る
- CookieではセッションIDのみを管理すればよくなるため、情報漏洩のリスクが減る
- インメモリDBなので高速な処理が可能
- インメモリDBは高速だがCookieに比べると処理が遅い
- Redisを導入するコストがかかる
- Redisに障害が発生すると、セッション機能が使えなくなる
Redisのインストール
RailsアプリケーションでRedisを利用する前に、まずはRedis本体をインストールします。
ローカル環境の場合
### redisのインストール
$ brew install redis
### redisサーバの起動
$ redis-server
Docker環境の場合
Redis用のコンテナをdocker-compose.ymlに追加すればOKです。
docker-compose.yml
version: '3'
services:
app: # アプリケーションコンテナ
...
...
(略)
depends_on:
- redis # redisコンテナを依存関係に追加
redis: # Redisコンテナ
image: redis:latest
volumes:
- redis-data:/data # Redisデータの永続化
volumes:
redis-data:
RailsアプリケーションにRedisを組み込む
RailsアプリケーションでRedisを利用する手順について紹介します。
gemのインストール
Redisを導入する際に利用するgemはredis-railsが有名です。
redis-railsはRailsアプリケーションのストア機能(キャッシュ、セッション、HTTPキャッシュ)をセットで提供するgemです。
しかしredis-railsのREADMEにも書いてあるように、セッション管理でRedisを使う場合はredis-actionpackの利用が推奨されているので、今回はredis-actionpackを利用します。
Gemfile
gem 'redis-actionpack'
$ bundle install
セッション管理の設定を作成
redis-actionpackのREADMEを参考に、設定を記載します。
セッション管理の設定はconfig.session_store
で行います。
config.session_store
を:redis_store
にすることでRedisがセッション管理で利用されます。
:redis_store
で設定できるオプションと意味は以下の通りです。1
オプション | 意味 |
---|---|
servers | Redisへの接続情報 |
expire_after | セッションキーのデフォルトのTTL(Time to live) |
key | セッションIDを保存するCookieの名前 |
threadsafe | スレッドセーフに関するフラグ。デフォルトはtrue |
secure | サーバからクライアントへのCookie転送でHTTPS通信を利用するかのフラグ |
signed | 署名/暗号化されたCookieの利用に関するフラグ |
httponly | HttpOnlyに関するフラグ |
なお、servers
はredis://<ホスト名>:<ポート番号>/<db番号>/<ネームスペース>
という命名規則です。SSL通信でRedisに接続する場合はredis
の部分をrediss
にします。
たとえば以下のようになります。
config/initializers/session_store.rb
Rails.application.config.session_store :redis_store,
servers: %w(redis://localhost:6379/0/session),
# ホスト: localhost(docker環境の場合はredisコンテナ名)
# ポート: 6379
# DB: 0番
# ネームスペース: session
expire_after: 90.minutes, # 有効期限90分
key: "_#{Rails.application.class.parent_name.downcase}_session" # キー名
環境ごとに設定を変えたい場合はconfig/environments/
配下の環境ファイルに設定を記述します。
config/environments/development.rb
Rails.application.configure do
(略)
config.session_store :redis_store,
servers: %w(redis://redis:6379/0/session),
...
...
end
Cookie方式とRedis方式のセッション情報管理の違いを確認する
Railsアプリケーションを起動し、Cookie方式とRedis方式の違いについて確認します。
Cookie方式の場合
Cookieにセッション情報がすべて保存されています。
Redis方式の場合
Cookie方式に比べ、Cookieに保存されている情報が少ないことがわかります。Redis方式の場合、Redisで管理されたセッション情報を取り出すためのIDだけがCookieに保存されます。
この時、Rails側でセッションに保存されているセッションIDを取得するとCookieに保存されている値と同じであることが確認できます。
RailsにおけるセッションとCookieの操作方法の詳細解説はRailsでセッションとCookieを操作する方法で紹介しています。
2: def index
=> 3: binding.pry
4: end
### Railsアプリケーションのセッションの保存先のCookie
> cookies[:_simpledevise_session]
=> "050c90ea9d875a5d11e04fe1274fc76f"
### セッションのキー一覧
> session.keys
=> ["_csrf_token"]
### セッションの値
> session[:_csrf_token]
=> "JqT7GxIDePWWOTihYTDee2NVUFCTma+9Cg9vSIlhOH4="
### セッションID
# Cookieの値と同じ、つまりCookieにはセッションIDが保存されている
session[:session_id]
=> "050c90ea9d875a5d11e04fe1274fc76f"
セッション情報はredis-cli
で確認できます。
アプリケーションにアクセスした後、redis-cli
でRedisの中身を確認すると、セッション情報の保存されたレコードが確認できます。
### redis-cliで接続
$ redis-cli -h localhost -p 6379 -n 0 --raw
# -h: ホスト指定
# -p: ポート指定
# -n: データベース選択
# --raw: マルチバイト文字の文字化けを防ぐ
### DBの選択(0~15まで選択)
> select 0
### 保存されているキーの数
> dbsize
1
### キーの一覧
> keys *
session:2::75605b9406802923576fc9d1d07df5d211cad8f380ff3a8dcb30a53612d02de1
# 接頭辞の『session:』部分がネームスペースに該当する
# ネームスペースを指定しない場合は『2::xxxxx』のようになる
### valueの種類の確認
> type session:2::75605b9406802923576fc9d1d07df5d211cad8f380ff3a8dcb30a53612d02de1
string
### valueの確認(stringのvalueはgetで取得する)
# session[:_csrf_token]の参照元
> get session:2::75605b9406802923576fc9d1d07df5d211cad8f380ff3a8dcb30a53612d02de1
{I"_csrf_token:EFI"1JqT7GxIDePWWOTihYTDee2NVUFCTma+9Cg9vSIlhOH4=;F
### 終了
> exit
なお、redis-cli
ではflushdb
でデータベースの全てのレコードが、del key
で対応するkeyのレコードが削除できます。
まとめ
- Redisをセッション管理に利用すると、Cookieで不要なデータを持たなくて済む
- RedisはインメモリDBなので高速な処理が可能
- Redisサーバを用意し、設定とgemを追加することでRailsとRedisの連携が可能
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!