DBベースのDeviseでのログイン情報の持ち方

DBベースのDeviseを利用したログイン処理や、管理者によるユーザー成りすましログイン時に、認証情報やセッション情報がどのように保持・管理されているのかを改めて整理してみました。

本検証で利用した主なGem

  • devise – ユーザー認証機能
  • activerecord-session_store – DBベースのセッション管理
目次

各種設定

セッション関連の設定概要

  • セッションストア: active_record_store(DBベース)
  • シリアライザー: :json
  • セッションキー: _devise_project_session
  • 設定ファイル:
    • config/initializers/session_store.rb – セッションストアの設定
      Rails.application.config.session_store :active_record_store, key: '_devise_project_session'

    • config/application.rb – シリアライザーの設定 # Configure session serializer ActiveRecord::SessionStore::Session.serializer = :json

:jsonシリアライザー

  • 内部的にはRubyのJSONモジュール(parse / generate)を使用
  • DB保存値は、データーベースの種類や参照方法に依存し、Base64エンコードされているケースと生データがそのまま入っているケースに分かれる。
    • SQLite3の場合、sessions.dataにBase64エンコードを実行した値が入っていた
      • Rails console経由では自動的にデシリアライズされて人間が読める形のHashとして参照可能
    • PostgreSQLの場合、sessions.dataにBase64エンコードされてない値が入っていた
      • sessions.data はSQLのWHERE句で検索可能
      • DB登録値を人間が直接みても把握しやすい
  • SQLite3等のBase64エンコードされた値が登録されている場合でも、Rails console経由では自動的にデシリアライズされて人間が読める形のHashとして参照できる

成りすましログイン実装

実装方法

今回は devise_masquerade Gem は使用せず、独自に成りすましログインを実装しています。

コントローラー

管理者用の成りすまし処理は、専用コントローラー
app/controllers/admins/masquerade_controller.rb
にて実装

  • create アクション: ユーザーとしてなりすましログイン
    • session[:admin_id] に管理者IDを保存
    • sign_in(user, scope: :user) でユーザーとしてログイン
    • 管理者とユーザーの両方のセッションを同時に保持
  • back アクション: 管理者に戻る
    • session[:admin_id] を削除
    • sign_out(:user) でユーザーからログアウト
    • 管理者は最初からログインしたままなので、再ログイン不要

動作の仕組み

  1. 管理者がユーザーとして成りすましログインすると、session[:admin_id]に管理者IDを保存
  2. Deviseのsign_inメソッドでscope: :userを指定してユーザーとしてログイン
  3. 管理者とユーザーのセッションが同時に保持される(Wardenの機能)
  4. 管理者に戻る際は、session[:admin_id]を削除し、ユーザーからログアウト
  5. 管理者のセッションは保持されているため、自動的に管理者としてログインした状態に戻る

挙動の確認

通常ログイン時の挙動

ユーザーとしてログインした際に、ブラウザ(Cookie)およびDB(sessionsテーブル)に保持される情報を確認します。

1. ログアウト状態でトップページにアクセスしてユーザーログイン画面に移動

cookie情報:

名前期限
_devise_project_session3d61eb186f276193f9b39960c19a1f24セッション

2. ユーザーとしてログイン

2-1. Remember me機能を利用しない場合

cookie情報:

名前期限
_devise_project_session31583c53362942cf35d9c80f132b8d87セッション

DB情報:

テーブル名.カラム名
sessions.session_id2::f6f080e4d69a6fd4656417df1025c18985119ff342156ed7b4e55a4af278e100
sessions.data{“value”:{“warden.user.user.key”:[[1],”$2a$12$GYNzAz1II/RDbA6.nvq0ae”],”flash”:{“discard”:[],”flashes”:{“notice”:”Signed in successfully.”}},”_csrf_token”:”rmYAA8tPTiPgC3f68k71-1SEY0SaUq62lMVrrDp_nOg”}}
users.id1
users.emailuser1@example.com
users.remember_created_atNULL

2-2. Remember me機能を利用した場合

cookie情報:

名前期限
_devise_project_session68d2c1c36f3fd0573c0dce3fa3c29744セッション
remember_user_tokeneyJfcmFpbHMiOnsibWVzc2FnZSI6Ilcxc3hYU3dpSkRKaEpERXlKRWRaVG5wQmVqRkpTUz..2026-01-21T04:16:07.000Z

DB情報:

テーブル名.カラム名
sessions.session_id2::c3a5e169d537d3ac871b58b11f2f97fc99f24bdc517fc70f508c290726770ed0
sessions.data{“value”:{“flash”:{“discard”:[],”flashes”:{“notice”:”Signed in successfully.”}},”warden.user.user.key”:[[1],”$2a$12$GYNzAz1II/RDbA6.nvq0ae”],”_csrf_token”:”ngh6n6CBifCfjW6JiTkr3bQvAcvjcGoVYooASYLIg9o”}}
users.id1
users.emailuser1@example.com
users.remember_created_at2026-01-07 04:16:07.910839

3. ログアウト実行

3-1. Remember me機能を利用しない場合

cookie情報:

名前期限
_devise_project_session0462a342200dab2686e39dc0f248147fセッション

DB情報:

テーブル名.カラム名
sessions.session_id2::edf7dbbadc9365f656643aafa2290de12db4c3a3ef5141d54088cc9691266820
sessions.data{“value”:{“flash”:{“discard”:[],”flashes”:{“notice”:”Signed out successfully.”}},”_csrf_token”:”XDJ4lP_s9S_pBf2bOy_n_JZ4ab9ft0wFSiNTnEFnTNg”}}
users.id1
users.emailuser1@example.com
users.remember_created_atNULL

3-2. Remember me機能を利用した場合

cookie情報:

名前期限
_devise_project_sessiond8550d86bf7d7666c53648950ecb9b6eセッション

DB情報:

テーブル名.カラム名
sessions.session_id2::ebc42a5957b7b2b0e16f54c036fe4a0c2f620f180b1d2f2a8f19d5290e081931
sessions.data{“value”:{“flash”:{“discard”:[],”flashes”:{“notice”:”Signed out successfully.”}},”_csrf_token”:”xkJTq4PsnulwO5YEkcDh2D_5FDqhTpcMsSpuPOtwmgo”}}
users.id1
users.emailuser1@example.com
users.remember_created_atNULL

代行ログイン時の挙動

管理者がユーザーとして成りすましログインを行った際の、ブラウザ側の保持情報とDB側の情報を確認します。
なおこちらは、ログイン前もDB情報を確認しています。

1. ログアウト状態でトップページにアクセスして管理者ログイン画面に移動

cookie情報:

名前期限
_devise_project_session30208199886f94c6d1b49c75c88436e2セッション

DB情報:

テーブル名.カラム名
sessions.id21
sessions.session_id2::ff0ada7f16c44bbaf03becb1d89075db289f32666b0a3ca60ffc3c69a63f7bab
sessions.data{“value”:{“_csrf_token”:”kAUCHbWQkptRXCjjbuSKQI2vgHyvp0v6aPj5o5FpGos”}}
admins.id1
admins.emailadmin@example.com
admins.remember_created_atNULL

2. 管理者としてログイン

※ Remember me機能を利用しない場合のみ実施

cookie情報:

名前期限
_devise_project_sessione509485017fe1845c44ae0f5df3658f9セッション

DB情報:

テーブル名.カラム名
sessions.id22
sessions.session_id2::eaa15dfd031aa539eaa570de66f94e686f63aa41f4aa34c6b5b2e680cea6cce4
sessions.data{“value”:{“warden.user.admin.key”:[[1],”$2a$12$7WI0p3xhsuv.PGH9eAkcoe”],”flash”:{“discard”:[],”flashes”:{“notice”:”Signed in successfully.”}},”_csrf_token”:”hl0BRIuhyRFgSwRpJyi_jYzvuCBptcV18vhfbfFEz4M”}}
admins.id1
admins.emailadmin@example.com

3. ユーザーで成りすましログイン

cookie情報:

名前期限
_devise_project_session0fed9dd74cb380d4b6c2ca4cc0a45d32セッション

DB情報:

テーブル名.カラム名
sessions.id23
sessions.session_id2::e569625366bf233c0b88f0ec4b96fc2203b9235121a2178eb78fa4faa70980f8
sessions.data{“value”:{“warden.user.admin.key”:[[1],”$2a$12$7WI0p3xhsuv.PGH9eAkcoe”],”flash”:{“discard”:[],”flashes”:{“notice”:”user2@example.comとしてログインしました”}},”_csrf_token”:”hl0BRIuhyRFgSwRpJyi_jYzvuCBptcV18vhfbfFEz4M”,”admin_id”:1,”warden.user.user.key”:[[2],”$2a$12$CRQBRFPsBNpJkcxBfPaMYu”]}}

4. 成りすましユーザーからログアウトして管理者に戻る

cookie情報:

名前期限
_devise_project_session0fed9dd74cb380d4b6c2ca4cc0a45d32セッション

DB情報:

テーブル名.カラム名
sessions.id23
sessions.session_id2::e569625366bf233c0b88f0ec4b96fc2203b9235121a2178eb78fa4faa70980f8
sessions.data{“value”:{“warden.user.admin.key”:[[1],”$2a$12$7WI0p3xhsuv.PGH9eAkcoe”],”flash”:{“discard”:[],”flashes”:{“notice”:”管理者に戻りました”}},”_csrf_token”:”hl0BRIuhyRFgSwRpJyi_jYzvuCBptcV18vhfbfFEz4M”}}
users.id1
users.emailuser1@example.com
users.remember_created_atNULL

5. 管理者からもログアウトする

cookie情報:

名前期限
_devise_project_session2d97e48df0b859c7f296939c078a0142セッション

DB情報:

テーブル名.カラム名
sessions.id24
sessions.session_id2::7d291b3f59bb886879269b3708a59a1b8324a04cab308985984cbd594f7f8fc7
sessions.data{“value”:{“flash”:{“discard”:[],”flashes”:{“notice”:”Signed out successfully.”}},”_csrf_token”:”ULFBdwfVWuNtVZpsblE88FcZelC_c1LThqtTJ_jyI2E”}}

検証結果

ログイン・ログアウト・成りすましといった操作のたびに、sessions.id, sessions.session_idや、ブラウザのセッション情報が変化することで、不正ログインを防ぐ仕組みになっていることが確認できました。

ユーザーサイドから考えると、普段からきちんとログアウトしておくのが重要であると再認識しました。

運用時のTips

成りすましログイン後にログアウトを行わず、別のユーザーへ続けて成りすましログインした場合の挙動

先に成りすました状態を維持したまま、後続のユーザー情報でセッション内容が更新される挙動が確認できました。
セッションデータ内のユーザー識別情報(warden.user.user.key)が、後続の成りすましログインによって上書きされています。

{
  "value": {
    "flash": {
      "discard": [],
      "flashes": {
        "notice": "user2@example.comとしてログインしました"
      }
    },
    "warden.user.admin.key": [[1], "$2a$12$7WI0p3xhsuv.PGH9eAkcoe"],
    "_csrf_token": "Ec7oxb5a3ss3VbRTRy-WfV1SO3VanJau-WEmcG-PJME",
    "admin_id": 1,
    "warden.user.user.key": [[2], "$2a$12$CRQBRFPsBNpJkcxBfPaMYu"]
  }
}

sessions テーブルが肥大化した場合の対処

ActiveRecord Session Store の公式ドキュメントでも言及されていますが、期限切れのセッションや不要なセッションデータが蓄積し続けるのを防ぐため、本番環境ではセッション削除用のタスクを定期的に実行することが推奨されています。
デフォルト設定では、一定期間(例:30日)更新されていないセッションが削除対象となり、この期間は環境変数によって調整可能です。

ActiveRecord Session Store 公式ドキュメント(2026年1月閲覧):
https://github.com/rails/activerecord-session_store/blob/master/README.md#installation

役に立ったらシェアしていただけると嬉しいです
  • URLをコピーしました!
  • URLをコピーしました!
目次