61

ユーザーがメールアドレスまたはユーザー名でログインできるようにする最善の方法は何ですか? 認証に warden + devise を使用しています。おそらくそれを行うのはそれほど難しくないと思いますが、必要なものすべてをどこに置くかについて、ここでアドバイスが必要だと思います. おそらく、デバイスはすでにこの機能を提供していますか? config/initializers/devise.rb のように、次のように記述します。

config.authentication_keys = [ :email, :username ]

サインインのためにユーザー名と電子メールの両方を要求するには。ビューで次のように見えるはずです。

Username or Email:
[____________________]

Password:
[____________________]

[Sign In]
4

11 に答える 11

47

問題の解決策を見つけました。私はこれに満足しているわけではありません (イニシャライザでこれを指定する方法があればよいのですが) が、今のところ機能しています。ユーザーモデルに次のメソッドを追加しました。

def self.find_for_database_authentication(conditions={})
  find_by(username: conditions[:email]) || find_by(email: conditions[:email])
end

@sguha と @Chetan が指摘したように、公式のデバイス wiki で別の優れたリソースを利用できます

于 2010-06-08T23:04:37.333 に答える
9
def self.find_for_authentication(conditions)
  conditions = ["username = ? or email = ?", conditions[authentication_keys.first], conditions[authentication_keys.first]]
  # raise StandardError, conditions.inspect
  super
end

彼らの例を使用してください!

于 2010-07-01T10:42:37.920 に答える
7

ユーザー名フィールドを追加済みであることを確認し、ユーザー名を attr_accessible に追加します。ユーザーにログイン仮想属性を作成する

1) ログインを attr_accessor として追加する

# Virtual attribute for authenticating by either username or email
# This is in addition to a real persisted field like 'username'
attr_accessor :login

2) ログインを attr_accessible に追加します

attr_accessible :login

authentication_keys で :login を使用するように Devise に指示します。

config/initializers/devise.rb を次のように変更します。

config.authentication_keys = [ :login ]

ユーザーのDeviseのfind_for_database_authenticationメソッドを上書きします

# Overrides the devise method find_for_authentication
# Allow users to Sign In using their username or email address
def self.find_for_authentication(conditions)
  login = conditions.delete(:login)
  where(conditions).where(["username = :value OR email = :value", { :value => login }]).first
end

ビューを更新する プロジェクトに Devise ビューがあることを確認して、カスタマイズできるようにします。

remove <%= f.label :email %>
remove <%= f.email_field :email %>
add <%= f.label :login %>   
add <%= f.text_field :login %>
于 2011-03-25T04:20:24.783 に答える
2

Platforma Tec (開発者) は、コントローラーにプラグインするのではなく、基盤となる Warden 認証戦略を使用するソリューションを github wiki に投稿しました。

https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address

(以前の回答にはリンクが壊れていましたが、これはこのリソースへのリンクを意図していたと思います。)

于 2011-10-18T20:46:39.400 に答える
2

https://gist.github.com/867932 : すべてに対する 1 つのソリューション。サインイン、パスワードを忘れた、確認、ロック解除の手順。

于 2011-03-13T06:48:17.097 に答える
1

squeel gemを使用すると、次のことができます。

  def self.find_for_authentication(conditions={})
    self.where{(email == conditions[:email]) | (username == conditions[:email])}.first
  end
于 2012-06-13T08:05:57.983 に答える
1

これは、@padde の回答をリファクタリングする Rails ソリューションです。ActiveRecord の find_by を使用して呼び出しを簡素化し、正規表現に基づいて呼び出しが 1 つだけであることを保証し、許可する場合は数値 ID もサポートします (スクリプト/API に役立ちます)。電子メールの正規表現は、このコンテキストで必要なだけ単純です。ユーザー名validtorが@文字を許可していないと想定しているため、@の存在を確認するだけです。

def self.find_for_database_authentication(conditions={})
  email = conditions[:email]
  if email =~ /@/ 
    self.find_by_email(email)
  elsif email.to_s =~ /\A[0-9]+\z/
    self.find(Integer(email))
  else
    self.find_by_username(email])
  end
end

wiki と @aku の回答と同様に、ここで :email を使用する代わりに、attr_accessible と authentication_keys を使用して新しい :login パラメータを作成することもお勧めします。(クイックフィックスを示すために、例では :email のままにしました。)

于 2013-03-07T05:24:53.467 に答える
1

私はこのように書きましたが、うまくいきました。それが「醜い修正」かどうかはわかりませんが、より良い解決策を思いついたらお知らせします...

 def self.authenticate(email, password)
   user = find_by_email(email) ||
     username = find_by_username(email)
   if user && user.password_hash = BCrypt::Engine.hash_secret(password, user.password_salt)
     user
   else
     nil
   end
end
于 2013-04-25T09:23:15.383 に答える
1

MongoDB (MongoIdを使用) を使用している場合は、別の方法でクエリを実行する必要があります。

  def self.find_for_database_authentication(conditions={})
    self.any_of({name: conditions[:email]},{email: conditions[:email]}).limit(1).first
  end

オンラインのどこかにあるように。

于 2011-10-14T05:16:30.660 に答える