2009-12-04 5 views
6

Unsere Rails-App verwendet Restful Authentication für die Benutzer-/Sitzungsverwaltung und es scheint, dass die Anmeldung an demselben Computer von mehreren Computern aus die Sitzung auf den anderen Computern beendet und die "Remember me" -Funktion beendet wird.Restful Authentication: Logins von mehreren Computern zulassen?

Also sagen, ich bin zu Hause und loggen Sie sich in die App ein (und aktivieren Sie "Remember me"). Dann gehe ich ins Büro und melde mich an (und checke auch "Remember me"). Wenn ich dann nach Hause zurückkehre, gehe ich zur App zurück und muss mich neu anmelden.

Wie kann ich die Anmeldung von mehreren Computern aus zulassen und die "Remember me" -Funktionalität über alle Benutzer hinweg beibehalten?

Antwort

9

Sie werden etwas Sicherheit opfern, indem Sie dies tun, aber es ist definitiv möglich. Es gibt zwei Möglichkeiten, wie Sie dies erreichen können.

In der ersten können Sie die Methode make_token in Ihrem Benutzermodell überschreiben. Das Modell wird derzeit wie folgt implementiert.

def make_token 
    secure_digest(Time.now, (1..10).map{ rand.to_s }) 
end 

Jedes Mal, wenn ein Benutzer anmeldet, mit oder ohne Cookies wird die make_token Methode, die ein neues remember_token für den Benutzer erzeugt genannt und speichert. Wenn Sie einen anderen Wert für den Benutzer hatten, der nicht erraten werden konnte, können Sie die -Methode ersetzen.

Dies würde sicherstellen, dass sich das Token nie ändert, aber es würde auch jeden aktivieren, der das Token erhalten hat, um sich als Benutzer auszugeben.

Wenn Sie einen Blick auf die handle_remember_cookie!-Methode in der Datei authenticated_system.rb werfen, sollten Sie in der Lage sein, diese Methode für Sie zu ändern.

def handle_remember_cookie!(new_cookie_flag) 
    return unless @current_<%= file_name %> 
    case 
    when valid_remember_cookie? then @current_<%= file_name %>.refresh_token # keeping same expiry date 
    when new_cookie_flag  then @current_<%= file_name %>.remember_me 
    else        @current_<%= file_name %>.forget_me 
    end 
    send_remember_cookie! 
end 

Sie werden bemerken, dass diese Methode drei Methoden im Benutzermodell nennt, refresh_token, remember_me und forget_me.

def remember_me 
    remember_me_for 2.weeks 
    end 

    def remember_me_for(time) 
    remember_me_until time.from_now.utc 
    end 

    def remember_me_until(time) 
    self.remember_token_expires_at = time 
    self.remember_token   = self.class.make_token 
    save(false) 
    end 

    # 
    # Deletes the server-side record of the authentication token. The 
    # client-side (browser cookie) and server-side (this remember_token) must 
    # always be deleted together. 
    # 
    def forget_me 
    self.remember_token_expires_at = nil 
    self.remember_token   = nil 
    save(false) 
    end 

    # refresh token (keeping same expires_at) if it exists 
    def refresh_token 
    if remember_token? 
     self.remember_token = self.class.make_token 
     save(false)  
    end 
    end 

Alle drei dieser Methoden setzen das Token zurück. forget_me setzt es auf nil, während die anderen beiden es auf den von make_token zurückgegebenen Wert setzen. Sie können diese Methoden im Benutzermodell überschreiben, um zu verhindern, dass sie das Token zurücksetzen, wenn es existiert und nicht abgelaufen ist. Das ist wahrscheinlich der beste Ansatz, oder Sie könnten der handle_remember_cookie!-Methode zusätzliche Logik hinzufügen, obwohl das wahrscheinlich mehr Arbeit wäre.

Wenn ich Sie wäre, würde ich remember_me_until, forget_me und refresh_token im Benutzermodell außer Kraft setzen. Folgendes sollte funktionieren.

Beachten Sie, dass Sie dadurch die Funktionen entfernen, die Sie vor Token-Diebstahl schützen. Aber das ist eine Kosten-Nutzen-Entscheidung, die Sie treffen können.

+0

Vielen Dank! Wie funktioniert nun die Funktionalität eines Benutzers, der "Remember me" überprüft? Erinnert sie sich noch an die Zeit, die in der Methode 'remember_me' festgelegt wurde? – Shpigford

+0

Sie merkt sich diese noch 2 Wochen, wie in der Methode remember_me, aber diese 2 Wochen beginnen mit der ersten Verwendung des Tokens. Mit anderen Worten: Wenn Sie sich von Computer A aus anmelden und sich 10 Tage von Computer B anmelden, läuft der Token 4 Tage später auf beiden Computern ab. – jcnnghm

+0

Großartig. Danke nochmal für deine Hilfe! – Shpigford

0

Sie können ändern, was die remember_token ist, um dies zu erreichen. Sie können es einstellen:

self.remember_token = encrypt("#{email}--extrajunkcharsforencryption") 

statt

self.remember_token = encrypt("#{email}--#{remember_token_expires_at}") 

Jetzt nichts Computer oder Zeit spezifisch über das Token ist, und Sie können in von mehreren Rechnern angemeldet bleiben.

+0

Hmmm, auf welche Version von Restful Authentication beziehen Sie sich? Ich benutze eine ziemlich neue Version und 'remember_token' ist mit einer viel komplexeren seriösen Methode und SHA1-Verschlüsselung eingestellt. – Shpigford

+1

Ah, Entschuldigung. Dies ist eine ziemlich alte Version, für die ich mindestens ein Jahr lang gearbeitet habe. Ich wusste nicht, dass es sich so sehr verändert hat. – erik

Verwandte Themen