6

Userモデルのパスワード検証とcreate_with_omniauth、ユーザーのFacebookアカウントから情報を取得する方法があります。

user.rb:

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation

  has_secure_password

  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence:   true,
                    format:     { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 6 }
  validates :password_confirmation, presence: true

  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["info"]["name"]
      user.email = auth["info"]["email"]
    end
  end
end

クリックlink_to "Sign in with Facebook, "auth/facebook"すると、次のエラーが発生します。

検証に失敗しました:パスワードを空白にすることはできません、パスワードを空白にすることはできません、パスワードが短すぎます(最小6文字)、パスワードの確認を空白にすることはできません

Userモデル内のこの2つの線のため、次のようになります。

 validates :password, presence: true, length: { minimum: 6 }
 validates :password_confirmation, presence: true

ユーザーがOmniAuthログイン方法でログインしようとしているときにその検証をバイパスするにはどうすればよいですか?

4

3 に答える 3

19

これは2つの方法で行うことができます。

1)パスワードフィールドにランダムに安全に生成された番号を保存するだけです(簡単で一貫性を維持できるため)個人的にこの方法を適用しました。ソーシャルサイトを介して署名したユーザーはサイトログインを介してログインしないためです。

2)または、attr_accesor

 :login_social (will be treated as boolean  
 validates :password, presence: true, length: { minimum: 6 }, :if => !login_social?
 validates :password_confirmation, presence: true, :if => :login_social?

ソーシャルサイトを介してログインするときはいつでも、このフィールドを真にしてください。私は2番目の方法に従い、最初の解決策に目を向けました。

個人的には、最初の方法を選択することをお勧めします

于 2012-11-02T05:15:57.573 に答える
4

@Aayushがソーシャルログインを検出するためのフィールドを作成することを提案したように、独自の検証を作成する代わりに、このdeviseメソッドをオーバーライドできます。

 def password_required?
     self.social_login? ? false : super
 end

あなたのモデルで例えばUser

于 2015-11-18T06:36:33.873 に答える
1

これに対する私の解決策は、omniauthユーザーに単純なパスワードを追加し、Railsがそれらのパスワードがomniauthユーザーであることを検出した場合にそれらのパスワードでサインインできないようにすることです。これにより、has_secure_passwordを引き続き使用できるため、ユーザーモデルが簡素化され、ソーシャルログインを使用する場合、パスワードは無関係になります(使用できなくなります)。

私のユーザーデータベーステーブルには次のものがあります。

  • 名前
  • Eメール
  • パスワード
  • password_confirmation
  • uid
  • プロバイダー

session_controller.rb

def create
  auth = request.env["omniauth.auth"]
  if auth
    sign_in_with_auth(auth)
  else
    sign_in_with_password
  end
end

session_helper.rb

def sign_in_with_auth(auth)
  user = User.find_by(uid: auth['uid'])
  if user
    #sign in the user
  else
    #create a user with any password.
    user = User.create! do |user|
      ...
      user.password = 'bojanglesicedtea'
      user.password_confirmation = 'bojanglesicedtea'
      user.provider = auth['provider']
    end
    #then sign in the user
  end
end

def sign_in_with_password
  user = User.find_by(email: params[:sessions][:email].downcase)
  if user == user.authenticate(params[:sessions][:password]) && user.provider.nil?
    #sign in the user
    #user.provider.nil? will be true only if it is not a social login user
  else
    #direct to error notification
  end
end
于 2013-08-16T19:25:34.980 に答える