2016-03-20 2 views
3

In unserer Multi-Tenant Rails 4.2 App möchten wir einen lokalen Thread current_token für User Modell definieren und beabsichtigen, es durch die ganze App zu verwenden. Hier ist die, wie die current_token definiert:Wie sicher ist der lokale Thread in Rails?

class User < ActiveRecord::Base 
    def self.current_token=(token) 
    Thread.current['current_token'] = token 
    end 

    def self.current_token 
    Thread.current['current_token'] 
    end 
end 

Das Token wird mit User.current_token abgerufen. Es ist wichtig, Thread während der gesamten Lebensdauer einer Benutzersitzung sicher und lebendig zu halten. Es wird darauf hingewiesen, dass der lokale Thread von einigen Webservern wie puma gelöscht werden kann. Wir würden gerne ein Feedback von der Community bekommen, wie Sound lokal in der realen Produktion ist. Welche Art von Problem sollten wir beachten (und mögliche Lösung, falls es eine gibt). Vielen Dank.

Antwort

5

Thread.current per se ist sicher. Das Risiko von Thread.current besteht darin, dass Sie es richtig verwenden müssen, da es am Ende einer Anfrage nicht automatisch zurückgesetzt wird. Einige Beispiele:

  • Stellen Sie sich ein Token in Thread.current in einer Anfrage festgelegt und nicht zu einem anderen Token in dem nächsten Satz (vielleicht, weil es keine Zeichen in der nächsten Anforderung waren), dann das alte Token wird nach wie vor verfügbar sein.

  • Oder Sie planen, Thread.current am Ende jeder Anfrage zu annullieren, um sicherzustellen, dass jede Anfrage mit einem leeren Thread.current beginnt. Wird passieren, wenn eine Anfrage mit einer Ausnahme fehlschlägt, wird sie trotzdem annulliert?

Es ist nur fehleranfällig mit Thread.current direkt zu arbeiten, und es besteht die Gefahr von Daten von einem Anfrage (ein Benutzer) auf einen späteren Antrag (Benutzer) auf dem gleichen Server auszusetzen.

Sie möchten vielleicht die RequestStore gem überprüfen, die intern Thread.current verwendet, aber es mit einigen Ebenen der Sicherheit verworfen.

+0

Die Übertragung eines alten Token nach thread.current ist ein echtes Problem. Wenn 'thread.current' in 'before_action' gelöscht und zurückgesetzt wird und in einer' after_action' in einem Controller gelöscht wird, wird das Risiko beseitigt? – user938363

+0

Meistens, aber Sie müssen auch über die Middleware nachdenken. Sehen Sie sich einmal an, wie das [RequestStore-Juwel] (https://github.com/steveklabnik/request_store/blob/master/lib/request_store/middleware.rb) dies handhabt. – spickermann

+0

Ersetzt das Anforderungsspeicher-Juwel 2 Probleme in Ihrem Beitrag? Ich möchte nur bestätigen. Ich habe ein paar Post über RequestStore gem gelesen und war mir nicht ganz sicher, was die Verwendung des Edelsteins betrifft. Danke vielmals. – user938363

1

Ich habe noch nie von einem Problem mit Puma und Thread Einheimischen gehört. Vielleicht möchten Sie das sentient_user gem verwenden, da sein Verhalten sehr nahe an dem ist, was Sie beschreiben. Der einzige Unterschied besteht darin, dass Sie den Token nicht um einen Token herum behalten, sondern den ganzen Benutzer.

Ich werde feststellen, dass dieses Muster im Grunde eine globale Variable ist, so dass es wie eine nicht angegebene Parameter für jede Methode, die es verwendet. Aber es kann gut für Auditing sein, so dass es immer verfügbar ist, egal wo Sie es brauchen.

+0

Danke für die Kommentare. – user938363