Frage

Ich habe alle meine Benutzer-Authentifizierung code in einem Ort, nämlich lib/auth.rb.Es sieht aus wie diese:

lib/auth.rb

module Admin

  def do_i_have_permission_to?(permission)
    # Code to check all of this goes here
  end

end

Ich schließe dieses Modul als Teil der Anwendung, der Helfer, so dass diese Funktionen stehen in allen Ansichten:

application_helper.rb

require 'auth'
module ApplicationHelper
  include Admin
  # other stuff here
end

Und außerdem habe ich es als Teil der application-controller, so dass der Controller ebenso können die Funktionen:

Anwendung.rb

require 'auth'
class ApplicationController < ActionController::Base
  include Admin
end

So weit, So gut.

Das problem ist, dass meine Anwendung nicht wie eine normale web-app.Speziell, mehr als kann ein Benutzer im system angemeldet sein von dem gleichen computer zur gleichen Zeit (mit dem browser).Ich mache Authentifizierung, für Maßnahmen mit Blick auf all die Leute, die angemeldet sind, die aus IP-und wenn Sie das können alle tun es, es geht.

Was dies bedeutet ist, dass, wenn ein admin etwas tun will, das hat admin zu melden Sie alle anderen zuerst, was ärgerlich ist.Aber wir wollen, dass die admin-Siegel auf alles, was der admin macht.So der Vorschlag, die mir gegeben war, haben Sie so die admin liefern kann eine Benutzername/Passwort-combo auf jeder Seite, auf die Sie normalerweise keinen Zugriff haben (z.B.ein 'Benutzer Bearbeiten' Seite, würde diese zusätzliche Eingabe-Felder) und die Authentifizierung Routinen würden überprüfen für Sie.Dies bedeutet, dass

Admin::do_i_have_permission_to?(permission)

muss bei der aktuellen Anforderung Parameter.Ich kann nicht nur, params[:foo] wie ich in einem controller, weil die Parameter nicht definiert ist;ebenso Anfrage.Parameter[:foo] wird auch nicht funktionieren.Meine Suche hat ergeben:

  • Die aktuellen such-Parameter werden in die aktuelle Anfrage,
  • Die aktuellen Anforderung ist in der aktuellen controller,
  • Die aktuellen controller in der aktuellen dispatcher, und
  • Ich bin nicht sicher, dass die aktuelle dispatcher gehalten wird überall.

Das heißt, die Erfahrung sagt mir, dass, wenn ich springen durch so viele Reifen haben, bin ich sehr wahrscheinlich Tun Es Falsch.Also, was ist der richtige Weg, es zu tun?Optionen, die ich betrachtet habe, sind:

  • Bewegen Sie einfach alle Funktionen, die derzeit in der auth.rb in den ApplicationHelper wo (denke ich), Sie werden haben Zugang zu ersuchen und solche.Funktioniert, aber clutters die Hölle aus der Hl.
  • Verschieben Sie alle Funktionen irgendwo anders Sie werden sehen, dass diese Methoden (ich weiß nicht, wo)
  • Ich bin einfach nur etwas fehlt.
War es hilfreich?

Lösung

In einem typischen Rails-Anwendung, die Authentifizierung Informationen werden in der aktiven session nicht den Parameter.Als solche, es ist ziemlich einfach zu schreiben, ein Helfer, der das tut, was Sie wollen.

Es scheint eher unorthodoxe erstellen Sie ein Modul, das wird dann in ApplicationHelper.Der traditionelle Ansatz ist die Erstellung eine separate Helfer, die in diesem Falle würde wohl genannt werden AuthenticationHelper.Dieses kann dann in einer beliebigen erforderlich Controller, oder wenn Sie es vorziehen, geladen in ApplicationController zur Verfügung zu stellen universell.

Im Allgemeinen, Helferinnen und Helfer sollten nicht für andere Helfer.Es ist besser zu laden Sie einfach mehrere Helfer in einem bestimmten Controller.

Helper-Methoden haben vollen Zugriff auf alle Instanz-Variablen, die innerhalb der controller-Kontext, in dem Sie tätig sind, aus.Um genau zu sein, sind diese Instanzvariablen nur (@name) und nicht-lokale Variablen (- Namen).Helper-Methoden ausgeführt werden, für eine bestimmte Ansicht als gut.

Weiter, ich bin mir nicht sicher, warum ein Benutzer auf die Bereitstellung von Anmeldeinformationen und ausführen eines Vorgangs im gleichen Schritt, zumindest für traditionelle web-based apps.Normalerweise ist der Prozess, um sich einzuloggen und dann eine Aktion ausführen, getrennt.

Jedoch, in die Fall von eine API, wo jede Transaktion ist ein eigenständiger Betrieb, der einfachste Ansatz ist, zu tun ist, ziehen Sie die gewünschte Anfrage Parameter, die sich mit Authentifizierung, etablieren einige controller-Instanz-Variablen, und fahren Sie dann zum ausführen der jeweiligen Anfrage, angesichts der Einschränkungen, die die Anmeldeinformationen zu verhängen.

Der Ansatz, dem ich Folgen in der Regel für diese Art der Sache ist die Schicht in eine Authentifizierung Struktur in den ApplicationController selbst, die können führen Sie die erforderlichen Prüfungen durch.Dies sind die geschützten Methoden.

Während es verlockend zu Rollen, in einen ganzen Haufen von Ihnen, wie can_edit_user?und can_create_group?diese sehr schnell aus der hand.Es ist ein einfaches design, ein Haken für eine Allgemeine-Zweck can_perform?oder has_authority_to?Methode übergeben wird, eine operation und alle erforderlichen Parameter.

Für Beispiel, eine sehr grobe Implementierung:

  class ApplicationController < ActionController::Base
  protected
    def has_authority_to?(operation, conditions = { })
      AuthenticationCheck.send(operation, conditions)
    rescue
      false
    end
  end

  module AuthenticationCheck
    def self.edit_user?(conditions)
      session_user == conditions[:user]
    end
  end

  class UserController
    # ...

    def edit
      @user = User.find(params[:id])

      unless (has_authority_to?(:edit_user, :user => @user))
        render(:partial => 'common/access_denied', :status => :forbidden)
      end
    rescue ActiveRecord::RecordNotFound
      render(:partial => 'users/not_found')
    end
  end

Natürlich würden Sie wollen, zu Rollen, eine Menge von der Behörde überprüft in before_filter Blöcke, um Wiederholungen zu vermeiden und um die Förderung der Konsistenz.

Eine vollständige framework-Beispiel könnte mehr helfen, wie das Armband der Benutzer-Authentifizierung-system:

http://github.com/theworkinggroup/wristband/tree/master

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top