2013-04-29 12 views
14

Ich suche nach einer Lösung, die es einem Benutzer in meiner App erlaubt, mehr als eine E-Mail zu haben. Dies sollte ähnlich wie Facebook, LinkedIn und Quora funktionieren. Wo ein Konto mehrere E-Mails haben kann, 1 als primäres.Gibt es eine Lösung für Rails Gem Devise, damit ein Benutzer mehrere E-Mails haben kann?

Gibt es eine schlüsselfertige Lösung für Geräte verfügbar? Ich hoffe, ich muss das nicht von Grund auf neu schreiben, da es so üblich ist.

Ideen? Dank

+0

Haben Sie zu-Anmeldung mit den sekundären E-Mails aktivieren möchten, für jeden Benutzer? – kiddorails

+0

Ja, ein Benutzer sollte sich nur mit einer seiner E-Mails anmelden können. Auch eine E-Mail sollte nicht in der Lage sein koexistieren zu können, eindeutige E-Mails pro Accounts über das gesamte System ... So wie Facebook damit umgeht ... – AnApprentice

+0

Mir ist eine bestehende Lösung dafür nicht bekannt, aber wenn Sie sich dazu entschließen schreibe es selbst, du könntest damit beginnen, das zumindest ähnlich ist (mehrere mögliche Login-Werte): https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in -using-ihre-Benutzername-oder-E-Mail-Adresse – MrTheWalrus

Antwort

15

Hm ... Ich schlage vor, würde neues Modell zu erstellen, Sie werden etwas tun:

Zum Beispiel Modell UserEmail wäre.

class UserEmail < ActiveRecord::Base 
    belongs_to :user 
end 

class User < ActiveRecord::Base 
    has_many :user_emails 
end 

und Methode der Überschreibung devise Rekord in User Modell zu finden:

def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if email = conditions.delete(:email) 
    User.includes(:user_emails).where('user_emails.email = ?', email).first 
    else 
    super(warden_conditions) 
    end 

mehr über Überschreibung Lesen Sie hier: https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address

+0

+1 sogar ich dachte genau das gleiche Lesen der Frage – Viren

+0

Dies wird (auf eine potenziell unsichere Weise) für andere Devise Nachschlagewerke, wie zum Beispiel einen Benutzer durch ihre Bestätigung Token oder zu finden Freischaltmarke Siehe meine Antwort für eine Lösung. – Brad

+0

Wie gehen Sie mit der Passwortwiederherstellung um? Was mache ich, wenn ich den Benutzer auswählen lassen möchte, an welche E-Mail der Link gesendet werden soll? – Gady

4

Ich würde Sie vorschlagen SecondaryEmail ein neues Modell zu erstellen.
Ein User kann has_many :secondary_emails, und jeder SecondaryEmailbelongs_to :user.

Sie müssen die Bestätigung der Eindeutigkeit für jede E-Mail in SecondaryEmail hinzufügen, und weiterhin müssen sicherstellen, dass keine neue SecondaryEmail bereits eine primäre E-Mail eines Benutzers ist.
Stellen Sie die Schnittstelle zur Verfügung, so dass ein User seine secondary_emails mit diesen Validierungen hinzufügen kann.

Im nächsten Schritt wird die SessionController von Devise überschrieben.
Richten Sie bei jedem Login-Vorgang Ihren Login-Vorgang für SecondaryEmail.where(:email => params[:email]) ein, wenn in den primären E-Mails des Benutzers keine E-Mail gefunden wird. Wenn es existiert, authentifizieren Sie sich mit dem Passwort dieses Benutzers, andernfalls existiert der Benutzer nicht.

Das ist, was ich bis jetzt gefunden habe. Ich würde wirklich gerne die Ansichten und den Ansatz der Experten darin kennenlernen. :)

1

Die Antworten hier sind ziemlich gut, und sollten Ihr Problem lösen. Um deine letzte Frage zu beantworten, denke ich nicht, dass du dafür ein Juwel finden wirst, da es zu einfach ist, obwohl es ziemlich üblich ist. Machen Sie es einfach von Grund auf neu, wie es vorgeschlagen wird, es sollte nicht zu viel Arbeit sein :)

8

Bobs Antwort ist nahe, aber es hat einen potenziell gefährlichen Fehler. Die find_first_by_auth_conditions Methode sollte wie folgt aussehen:

def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if email = conditions.delete(:email) 
    User.includes(:user_emails).where('user_emails.email = ?', email).first 
    else 
    super(warden_conditions) 
    end 
end 

Die E-Mail-Check und rufen zu super ist wichtig, denn auch diese Devise Methode verwendet User s durch confirmation_token, unlock_token und reset_token nachzuschlagen. Ohne den else-Zweig werden alle Aufrufe dieser Methode, die keinen email-Parameter aufweisen, entweder fehlschlagen oder ein Benutzer mit einer nil-E-Mail laden.

+2

Danke) Aktualisiere meine Antwort) – Bob

3

Ich bin vor einer Weile auf dieses Problem gestoßen - und habe die Lösung in my blog umrissen.

Die Schritte sind nachstehend zusammengefasst:

  • E-Mail-Informationen haben in einem weiteren Modell gespeichert werden, sagen Email. So hat ein User viele verwandte Email Instanzen.
  • Wir würden höchstwahrscheinlich eine E-Mail als Standard-E-Mail festlegen, die wir für die Kommunikation mit dem Benutzer verwenden können.
  • Die Klassenmethode der User Klasse find_first_by_auth_conditions wird verwendet, um den Benutzer nach den angegebenen Anmeldeinformationen zu suchen. Daher müssen wir diese Methode überschreiben, um mit dem Modell Email zu suchen.
  • Wir müssen die Standardansichten ändern, weil sie implizit das Vorhandensein von email Methode des Benutzers annehmen. Anstatt die Ansichten vollständig neu zu schreiben, können wir einen Proxy-Accessor für E-Mail hinzufügen, der an die Standard-E-Mail für den Benutzer delegiert.
  • Wenn ein Benutzer mehrere E-Mails haben darf, möchten wir Ihnen auch die Möglichkeit bieten, auf der Seite zum Bearbeiten von Accounts E-Mails hinzuzufügen oder zu entfernen.
  • Wenn Sie omniauth Integration benötigen - dann muss die Lagerbestandsimplementierung von User.from_omniauth, die im Devise-Wiki beschrieben wird, modifiziert werden, um mehrere E-Mails zu unterstützen.

Meine Implementierung ist verfügbar .

0

Sie können den devise-multi_email gem verwenden: https://github.com/allenwq/devise-multi_email

ersetzen devise :authenticatable mit devise :multi_email_authenticatable, so dass Ihre Modelle aussehen könnte:

class User < ActiveRecord::Base 
    has_many :emails 

    # Replace :database_authenticatable, with :multi_email_authenticatable 
    devise :multi_email_authenticatable, :registerable 
end 

class Email < ActiveRecord::Base 
    belongs_to :user 
end 

Und wenn Sie die E-Mails zusammen werden alle wollen nfirmable und erholen Sie Ihr Passwort von jedem Ihrer E-Mails, nur

devise :multi_email_authenticatable, :multi_email_confirmable, :confirmable

Verwandte Themen