akishin999の日記

調べた事などを書いて行きます。

restful-authentication から sorcery に乗り換える

今更といえば今更なのですが、Rails 2.x で作ったアプリケーションを Rails 3.2 に移行しました。

ただ、該当アプリケーションでは認証プラグインとして restful-authentication を採用していたため、そのままでは 3.2 で動かす事はできません。
単純に DeviseSorcery に移行してしまっても良いのですが、パスワード暗号化のロジックが異なると登録済みのユーザのパスワードを全て変更する必要が出てきてしまいます。

というわけで、 Sorcery の custom_encryption_provider を作成し、 restful-authentication で作成したユーザをそのまま使用できるようにしてみました。

まずは以下のように $RAILS_ROOT/lib/sorcery/crypto_providers/restful_authentication.rb を作成します。

  • lib/sorcery/crypto_providers/restful_authentication.rb

restful_authentication は SHA1 を使用してパスワードをハッシュ化していたので、Sorcery の CryptoProviders として提供されている SHA1 クラスを拡張して作成しました。

また、 restful-authentication では config/initializers/site_keys.rb に設定されている REST_AUTH_SITE_KEY をこのファイルに持ってきます。

次に lib 以下のクラスを Rails が autoload してくれるようにするため、config/application.rb に以下の設定を追記します。

config.autoload_paths += %W(#{config.root}/lib)

最後に config/initializers/sorcery.rb の以下の設定を変更します。

# restful-authentication でのユーザ名カラムに変更する
user.username_attribute_names = [:login]

# restful-authentication に合わせて「--」を指定
user.salt_join_token = "--"

# restful-authentication の config/initializers/site_keys.rb に設定されている
# REST_AUTH_DIGEST_STRETCHES の値と同じ値を設定する
user.stretches = 10

# 作成した RestfulAuthentication クラスを指定
user.custom_encryption_provider = ::Sorcery::CryptoProviders::RestfulAuthentication

# custom_encryption_provider を使用するので :custom を指定
user.encryption_algorithm = :custom

これで移行したアプリケーションでも restful-authentication で作成したユーザでログインできるようになるはずです。
確認したい場合は rails console で以下のように User.authenticate メソッドでユーザが取得できれば成功です。

% rails c
> User.authenticate 'username', 'password'


Railsプラグインは確かに開発時の生産性は上がるのでとても便利なのですが、こうやって更新されなくなった場合の移行コストはやはりそれなりに高いですね。
まぁそこはプロトタイプ作成時の速度を優先、という事で割り切りなのかも知れませんが。

そろそろ Java でいう Apache Commons のような、ある程度将来的にちゃんと更新されて行きそうなプラグイン配布コミュニティとか出てきてくれると嬉しいかなー。