💎

🔒 カスタムWarden戦略による高度なセッション管理

に公開

Deviseは内部でWardenを使用しており、これを拡張することで、トークンのローテーション、デバイスフィンガープリント、または二要素認証のトリガーなど、カスタム認証フローを実装できます。カスタムWarden戦略を作成することで、Deviseのコアを変更せずに、クレデンシャルの検証方法やセッションの管理を完全に制御できます。

1. 戦略の定義

例1: JWTトークンによる認証

以下はJWTを使用して認証する戦略です:

# config/initializers/warden_strategies.rb
require 'base64'

Warden::Strategies.add(:token_strategy) do
  def valid?
    request.headers['Authorization'].present?
  end

  def authenticate!
    token = request.headers['Authorization']&.split(' ')&.last
    payload = JWT.decode(token, Rails.application.credentials.secret_key_base)[0]
    user = User.find_by(id: payload['sub'], token_version: payload['ver'])

    user ? success!(user) : fail!('無効または期限切れのトークン')
  rescue JWT::DecodeError
    fail!('無効なトークン')
  end
end

この戦略は、Authorizationヘッダーからトークンを抽出し、JWTをデコードしてユーザーを認証します。トークンが無効または期限切れの場合、エラーを返します。

例2: APIキーによる認証

以下はAPIキーを使用した別の認証戦略です:

# config/initializers/warden_strategies.rb
Warden::Strategies.add(:api_key_strategy) do
  def valid?
    request.headers['X-API-Key'].present?
  end

  def authenticate!
    api_key = request.headers['X-API-Key']
    user = User.find_by(api_key: api_key, active: true)

    user ? success!(user) : fail!('APIキーが無効またはユーザーが非アクティブです')
  end
end

この戦略は、X-API-Keyヘッダーをチェックし、データベース内でAPIキーに対応するユーザーを見つけます。ユーザーまたはAPIキーが無効な場合、認証は失敗します。

2. Deviseへのフック

以下の設定で、定義した戦略をDeviseに統合します:

# config/initializers/devise.rb
Devise.setup do |config|
  config.warden do |manager|
    manager.default_strategies(scope: :user).unshift :token_strategy, :api_key_strategy
  end
end

この設定により、標準のdatabase_authenticatable戦略の前にtoken_strategyおよびapi_key_strategyが実行され、APIリクエストを柔軟に認証できます。

これらのカスタムWarden戦略を使用することで、多様で安全な認証フローを実装し、Deviseの標準機能を超えた高度なセッション管理を実現できます。

参考文献
get-smart GitHub Repository: RubyやRailsアプリケーションの開発を効率化するための便利なツールとヒントを提供するリソース。

Discussion