rails のセッション管理に redis を導入する

以前、rails に redis を導入するという記事を書きました。
その際は、rails の提供するキャッシュの仕組み(Rails.cache)に、redis を使用しました。

今回は、セッション管理に redis を適用してみます。

目次

参考

実行環境

  • windows
    • Windows10 ver.1909
  • Mac
    • macOS Mojave 10.14.4

参考

事前準備

事前準備として、devise gem を使用して、ログインを行うアプリケーションを作ってあるものとします。
やり方は、本ブログでたくさん扱っているので、参照ください。

Octo’s blog - devise の関連記事

redis サーバーは、localhost:6379でアクセスできるものとします。

その 1 (redis-rails を用いてフラグメントキャッシュストアで設定)

導入

Gemfile にgem 'redis-rails'を記述してbundle installを実行します。

設定 1

config/environments/[実行環境(developmentとか)].rbのファイルに以下を記述します。
今回は、config/environments/development.rbへの記述を例にとります。

config/environments/development.rb
1
2
3
4
5
6
7
Rails.application.configure do
# 省略

config.session_store :redis_store, servers: 'redis://localhost:6379/0/cache', expire_after: 1.day

# 省略
end

'redis://localhost:6379/0/cache'の記述は、以下のように分解できます、
'redis://[ホスト名]:[ポート]/[db]/[namespase]'

  • [ホスト名] まんまですね。ホスト名です。

  • [ポート番号] まんまですね。ポート番号です。

  • [db]の部分には、整数値を入れることができます。デフォルト値が 0 なので、設定しないこともできます
    ("databese1"のように文字列を設定したらデフォルト値が適用されていました。)

  • [namespase]の部分を設定することで、書き込む際のキーに接頭辞の形で付与されます。

また、redis-store/redis-railsでは、以下のようにハッシュで渡す書き方も紹介されています。redis サーバーにパスワード設定があるなら、以下の書き方をしてゆくことになりそうです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Rails.application.configure do
# 省略

config.cache_store = :redis_store, {
host: "localhost",
port: 6379,
db: 0,
password: "password",
namespace: "cache"
}, {
expires_in: 1.day
}

# 省略
end

今回は、以下の記述を採用します。

config/environments/development.rb
1
2
3
4
5
6
7
Rails.application.configure do
# 省略

config.session_store :redis_store, servers: 'redis://localhost:6379/', expire_after: 1.day

# 省略
end

動作確認 1

bundle exec rails sで起動し、適当にログインしてみます。

コンソールから、以下のように redis の持っているキーを確認します。

1
2
3
4
5
redis-cli

127.0.0.1:6379> keys *
1) "2::f7e173d9971def6ddc129d5e938a4ed5d1d0046b3b5020add20c5f49e4cede82"
# 以下省略

2::から連なるキーが保管されています。

試しに、DEL "2::f7e173d9971def6ddc129d5e938a4ed5d1d0046b3b5020add20c5f49e4cede82"を実行してみます。
ブラウザでリロードをすると、ログイン前ページにリダイレクトされます。
セッションの値がなくなったので、強制退出させられることを確認できました。

その 2 (redis-rails を用いてセッションストレージストアで設定)

設定 2

今度は、redis-store/redis-railsで紹介されているセッションストレージを試します。
README に倣い、config/initializers/session_store.rbを作成します。
フラグメントキャッシュストアを確認した際には、db は デフォルト値の 0、namespace は未設定だったので、こちらは詳細に設定してみます。

config/initializers/session_store.rb
1
2
3
4
5
6
7
8
9
Rails.application.config.session_store :redis_store, expire_after: 1.day, servers: {
host: "localhost",
port: 6379,
#password: 'password', 今回は使わない
db: 1,
namespace: "session",
signed: true, # 署名、暗号化されたcookieを使用する
secure: true # HTTPS 接続でサーバーからクライアントにcookieが転送されるようにする
}

もし動作環境ごとに、設定を変える場合、config/environments/のように設定ファイルが分離していないので、以下のような記述が必要そうです。

config/initializers/session_store.rb(環境ごとに設定を分離)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if Rails.env.production?
# production用設定
Rails.application.config.session_store :redis_store, expire_after: 1.day, servers: {
host: "localhost",
port: 6379,
#password: 'password', 今回は使わない
db: 1,
namespace: "session",
signed: true, # 署名、暗号化されたcookieを使用する
secure: true # HTTPS 接続でサーバーからクライアントにcookieが転送されるようにする
}
elsif Rails.env.test?
# test用設定
# 省略
end

今回の確認では、developmentで動作させるので、行いません。

確認 2

bundle exec rails sで起動し、改めてログインしてみます。

コンソールから、redis の持っているキーを確認します。

1
2
3
4
5
6
redis-cli

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "session:2::b50b10d0792b991673261a3648b612d920dcef54b1567b16444341598b413134"

db=1session:2::から連なるキーが保管されていることが確認できます。

その 3 (redis-actionpack を用いてセッションストレージストアで設定)

redis-railsgem はよく使われる gem のようなのですが、実は、以下の文言が書かれています。

If you need session storage, consider directly using redis-actionpack instead.
「セッションストレージを使いたいならredis-actionpackを使ってほしい(雑な意訳)」とのことです。

redis-actionpackを用いて設定してみます。

導入

Gemfile の記述を以下のように変更してbundle installを実行します。

1
2
#gem 'redis-rails' # redis-railsはコメントアウトしておく
gem 'redis-actionpack'

設定 3

redis-rails を用いてセッションストレージストアで設定したものと同様にconfig/initializers/session_store.rbを作成します。
比較のため、db のみ 2 に変更します。

config/initializers/session_store.rb
1
2
3
4
5
6
7
8
9
Rails.application.config.session_store :redis_store, expire_after: 1.day, servers: {
host: "localhost",
port: 6379,
#password: 'password', 今回は使わない
db: 2,
namespace: "session",
signed: true, # 署名、暗号化されたcookieを使用する
secure: true # HTTPS 接続でサーバーからクライアントにcookieが転送されるようにする
}

確認 3

bundle exec rails sで起動し、再度ログインしてみます。

コンソールから、redis の持っているキーを確認します。

1
2
3
4
5
6
redis-cli

127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> keys *
1) "session:2::8793e017ca7e630366eebbd5099ead71ecea0c2a32987945a834667aa8ea43a3"

redis サーバーにセッションを書き込めているようです。

ちなみに、最初に試したconfig/environments/development.rbでの設定もできました。

config/environments/development.rb
1
2
3
4
5
6
7
Rails.application.configure do
# 省略

config.session_store :redis_store, servers: 'redis://localhost:6379/', expire_after: 1.day

# 省略
end

‘redis-actionpack’が、’redis-rails’に含まれていることから結局のところ’redis-actionpack’を設定をしていたということのようです。


今回は、rails のセッション管理を redis サーバーで行ってみました。
コンソールを使い、書き込まれているセッションの値を確認・削除して強制的にログアウトさせたことで、ぼんやりとしてたものがはっきりしたように感じます。

ではでは。