Authlogicに関するメモ
認証機能再発明するべからずは有名な鉄則ですが、まるで知らないままというのもマズイので実装を読むことでお茶を濁していきたい。
salt
やSCrypt
の運用、persistence_token
の更新などで比較的安全にいけるのでは。
パスワード
salt
Authlogic::Random.friendly_token
def friendly_token # use base64url as defined by RFC4648 SecureRandom.base64(15).tr('+/=', '').strip.delete("\n") end
暗号化
authlogic/lib/authlogic/crypto_providers
以下に、各種Cryptorをラップしたアダプターがある。
SCrypt
ならAuthlogic::CryptoProviders::SCrypt#encrypt(*tokens)
で暗号化パスワードを得られる。
*tokens
には[password, salt]
が入り、salt
は保存されてログイン時のパスワード一致を見る時に使われる。
生パスワードは勿論破棄される。
パスワード確認
各種Cryptorの比較演算子を使ったりする。
# ユーザーのレコードから得る salt = user.password_salt encrypted = user.encryped_password # 入力 password = 'aaaaaaaa' # 比較 SCrypt::Password.new(encrypted) == Authlogic::CryptoProviders::SCrypt.encrypt(password, salt)
セッション
cookie
などの値を得るために、Controller
インスタンスを持つアダプターが必要になる。
Controller
経由では、初期化時に自動的に付与されるAuthlogic::ControllerAdapters::RailsAdapter
が設定する。
Authlogic::Session::Base.controller = RailsAdapter.new(self)
それ以外で使いたい場合は、必要な値を返すなにかを用意する。
class ControllerLike def initialize(request) @request = request end def cookies @request.cookies end def params @request.params end def session @request.session end def responds_to_last_request_update_allowed? true end def last_request_update_allowed? false end def method_missing(*args) false end end Authlogic::Session::Base.controller = ControllerLike.new(request)
開始
create
時にユーザーレコードにpersistence_token
を保存する。
クッキーにはそのpersistence_token
とユーザーのid
を、後にsplit
可能な形で保存する。[persistence_token, id].join('::')
など。
復元
保存しておいたクッキーの値のid
からユーザーを検索、persistence_token
と一致するか見る。