web-dev-qa-db-ja.com

RoR Devise:ユーザー名OR emailでサインイン

ユーザーが自分のメールアドレスでログインできるようにするための最良の方法は何ですかORユーザー名?認証に監視員+工夫を使用しています。おそらくdeviseがすでにこの機能を提供しているのでしょうか?config/initializers/devise.rbのように書いてください:

config.authentication_keys = [ :email, :username ]

サインインにユーザー名と電子メールの両方を要求するため。単にASCIIアートを使用すると、ビューでは次のようになります。

Username or Email:
[____________________]

Password:
[____________________]

[Sign In]
59
Patrick Oscity

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

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

@sguhaと@Chetanが指摘したように、 別の素晴らしいリソースが公式のdev wikiで利用可能です

46
Patrick Oscity
25
Chetan
def self.find_for_authentication(conditions)
  conditions = ["username = ? or email = ?", conditions[authentication_keys.first], conditions[authentication_keys.first]]
  # raise StandardError, conditions.inspect
  super
end

例を使用してください!

9

ユーザー名フィールドがすでに追加されていることを確認し、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

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

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 %>
7
aku

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

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

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

2
Mike Jarema

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

2
Kulbir Saini

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

  def self.find_for_authentication(conditions={})
    self.where{(email == conditions[:email]) | (username == conditions[:email])}.first
  end
1
tarmo

私はこのように書いて、うまくいきました。 「ugい修正」であるかどうかはわかりませんが、より良い解決策を思い付くなら、お知らせします...

 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
1
maverick

私はこれにクイックハックを使用して、デバイス固有のコードの変更を避け、特定のシナリオに使用します(特に、モバイルアプリがサーバー上にユーザーを作成できるAPIに使用します)。

Before_filterをすべてのデバイスコントローラーに追加し、ユーザー名が渡される場合、ユーザー名( "#{params [:user] [:username]} @ mycustomdomain.com")から電子メールを生成し、ユーザーを保存します。他のすべての呼び出しについても、同じロジックに基づいて電子メールを生成します。 before_filterは次のようになります。

def generate_email_for_username
    return if(!params[:user][:email].blank? || params[:user][:username].blank?)
    params[:user][:email] = "#{params[:user][:username]}@mycustomdomain.com"
end

また、usersテーブルにユーザー名を保存しているので、@ mycustomdomain.comで終わる電子メールを持つユーザーがユーザー名を使用して作成されたことがわかります。

1
amit_saxena

MongoDB(MongoIdを使用)を使用している場合、異なるクエリを実行する必要があります。

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

それだけでオンラインのどこかになります。

1
CamelCamelCamel

Rails @paddeの答えをリファクタリングするソリューションです。ActiveRecordのfind_byを使用して呼び出しを簡素化し、正規表現に基づいて呼び出しが1つのみであることを確認し、それを許可する場合は数値IDもサポートします(電子メールの正規表現は、このコンテキストで必要なだけ簡単です。ユーザー名バリデーターで@文字が許可されていないことを前提として、@の存在を確認するだけです。

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のままにしました。)

1
mahemoff