2011-09-21 4 views
8

私はプロジェクトをRails 3から3.1に移植しています。私の認証システムはActiveRecordの新しいhas_secure_passwordに簡単に切り替えられました。私が実行している唯一の問題は、OmniAuthも使用しているため、システムをセットアップしているため、ユーザーがOmniAuthプロバイダーの1つを使用してサインアップした場合、アカウントにはパスワードは必要ありません。私はhas_secure_passwordでpassword_digestバリデーションの設定を上書きすることはできません。これらのバリデーションを無効にして自分自身を書き留めてもらえませんか?それとも、私の古い手書きのbcrypt関数を自分のRails 3バージョンのサイトから使用するだけですか?Rails 3.1のhas_secure_passwordがOmniAuthとうまく動作するようにする

答えて

5

私は結局、カスタムメソッドの使用に戻りました。しかし、後で私はbefore_validationコールバックを使って条件を確認してから、password_digestを '0'のような単純なものに設定していればよいはずです。このようにしてダイジェストは空白にならず、同時に正しいパスワードとして検証してOmniAuthを使用してサインインする必要がありません。

私が間違っていると私を修正することは自由に感じてください。

+0

私はあなたの方法を試してみるつもりです、もしあなたがより良い方法を見つけたら教えてください。 –

+3

これは簡単な修正のようです。私は 'from_omniauth'メソッドで' user.password_digest = SecureRandom.urlsafe_base64'を設定しました。 (あなたの答えを読み返した後、認証に使用されていないのでランダム化する必要はありません)。これははるかに迅速です - 私は合理的な答えが受け入れられた答えを選ぶために何ですか? – umezo

+0

あなたは正しいです。私は先に進んで答えを切り替えた。私はまだBCryptを直接使用し、独自のパスワードハッシュ方法を書いていますが。それはやりすぎて、あなたの意図をより明確にします。 –

4

Scott、あなたの考えは正しいです。私はこの問題で無駄に取り組んできました。私は 'has_secure_password'を上書きしようとしましたが、それは単に動作しません。どこにコードを貼っても問題ありません。誰かが認証またはサインアップしようとしているとき

class User < ActiveRecord::Base 
    has_secure_password 

    validates_presence_of :password, :on => :create, :if => :password_required 

    # Associations 
    has_many :authentications 

    # Callbacks 
    before_validation :no_password_omniauth 

    # Gets set to true if the caller is trying to authenticate with omniauth. 
    @called_omniauth = false 

    # Build new omniauth users 
    def apply_omniauth(omniauth) 
    authentications.build(
    :provider => omniauth['provider'], 
    :uid => omniauth['uid']) 
    self.first_name = omniauth['user_info']['first_name'] if self.first_name.blank? 
    self.last_name = omniauth['user_info']['last_name'] if self.last_name.blank? 
    self.email = omniauth['user_info']['email'] if omniauth['user_info']['email'] && self.email.blank? 
    @called_omniauth = true 
    end 

    def password_required 
    return false if @called_omniauth == true 
    (authentications.empty? || !password.blank?) 
    end 

    private 

    def no_password_omniauth 
    self.password_digest = 0 unless password_required 
    end 

end 

apply_omniauth方法は、コントローラから呼び出さ:

は、代わりに私は、次があります。

あなたがそれを釘付けにしてくれたことをありがとう。

+0

コード例を提供して以来、私はあなたの答えに切り替えました。ありがとう。私はそれを仮定すると、それはあなたがパスワードの任意の種類を使用してそのアカウントにログインさせることはできません? –

+0

また、 '@ called_omniauth'を正確に何を使用していますか? 'authentications.emptyを使うだけではないのですか? || !password.blank? 'あなたの' password_required'メソッドで十分でしょうか? –

+0

アプリケーションがomniauthを使って(apply_omniauthメソッドによって)サインアップしていることをアプリケーションが知っている唯一の方法は、called_omniauthです。 – chourobin