Vollständige Version anzeigen : Login im preDispatch
Aloha,
ich kenne OOP zwar seit Jahren, habe aber irgendwie doch immer -äh (nachschlag)- imperativ programmiert. Ich hoffe, dass sich das mit dem ZF endlich ändern wird ;).
Derzeit beschäftige ich mich mit dem Controller und Auth, die ich in ein praktisches Paket zusammenschnüren möchte.
Die Idee hier ist, dass egal welche URL aufgerufen wird, geprüft wird, ob der Nutzer überhaupt eingeloggt ist, falls nicht bekommt er das Login-Formular angezeigt. Nach dem Login soll er aber auf der Seite landen, die er auf aufgerufen hat (und nicht auf einer Startseite in der Applikation oder ähnliches).
Um das umzusetzen, habe ich mir testweise ein kleines Plugin geschrieben, das im preDispatch() die nötigen Schritte ausführt:
class AuthPlugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
if ($request->getParam('logout')==1) {
Zend_Auth::getInstance()->clearIdentity();
}
if ($request->getParam('formaction')=='login') {
// TODO input validation...
$_authAdapter = Zend_Registry::get('authAdapter'); // put this in a constructor?
$_authAdapter->setIdentity($request->getParam('user'))
->setCredential($request->getParam('pass'));
$result = Zend_Auth::getInstance()->authenticate($_authAdapter);
// TODO restore parameters of the called page
}
// User is logged in
if (Zend_Auth::getInstance()->hasIdentity()) return;
// User is not logged in => forward to login.
// same as _forward('login', 'index', 'default'); (which only exists in controllers)
$request -> setActionName('login')
-> setControllerName('index')
-> setModuleName('default');
}
}Grundsätzlich funktioniert das in dem kleinen gegebenen Rahmen, aber ist die Herangehensweise überhaupt korrekt?
Ausserdem bin ich mir noch nicht ganz sicher, wie ich die (eventuell aus einem Formular stammenden) Parameter dann durchschleifen könnte: einfach als versteckte Formularfelder? Oder lass ich diesen Part weg? ;)
Balu
DennisBecker
25.09.2007, 15:21
Also wenn ein User eingeloggt ist dann gibt es in der Session den Namespace "Zend_Auth" - da steht alles drin :) Diesen Namespace ruft man aber nicht explizit auf sondern geht über die Zend_Auth Methoden. Am betsen loggst du dich mal ein und gibst Zend_Debug::dump($_SESSION) aus :)
KingCrunch
25.09.2007, 15:44
$auth = Zend_Auth::getInstance();
Zend_Debug::dump ($auth->getIdentity());
Zend_Debug::dump ($auth->hasIdentity());Im Sinne des Konzeptes nie auf $_SESSION direkt zugreifen und Namespaces, die mit Zend_ beginnen sind auch Tabu.
DennisBecker
25.09.2007, 16:15
Joa, aber ein Zend_Debug::dum() darauf macht ja nichts, er liest es nur aus :) So kann man auch mal nachschauen, was denn so alles in der Session steht.
KingCrunch
25.09.2007, 16:31
Stimmt, dachte mir bloss, dass das mal ganz interessant sei :D Das sind die beiden Methoden aus Zend_Auth, die interessant für dein Vorhanden sein dürften. Solange hasIdentity false liefert, speicherst du die Requestparameter in der Session, leitest auf Login um und wenn dann mal ein Login erfolgreich war, leitest du wieder zu der Seite um, die die Requestparameter hergeben. Aber aufpassen: Wenn du deine Login-Seite aufrufst, darf er natürlich nicht auf die Login-Seite umleiten :D
DennisBecker
25.09.2007, 16:34
Ich habe mir ein Plugin geschrieben, welches immer im postDispatch() die $_SERVER['REQUEST_URI'] in die Session schreibt ("Default" Namespace). Dann brauch ich nur den Wert dort verwenden zum umleiten :) Beim Login landet der User erstmal auf die Startseite (denn woanders kann er garnicht hin).
KingCrunch
25.09.2007, 16:42
Hmm ... Ist im postDisptach nicht etwas spät? Also nehmen wir an, jemand ruft eine (zugegeben völlig bekloppte :D) Methode deleteAll auf. Wenn erst nach der Aktion festgestellt wurde, dass er es garnicht darf, is auch irgendwie schlecht :D
Geändert von Radhad (Heute um 16:38 Uhr). Grund: Rechtschreibfehler *arghs* :)Wenigstens wer, der drauf achtet :D
DennisBecker
25.09.2007, 16:44
Ich mach ja nicht die Authentifizierung im portDispatch, nur die Session-Variable "lastUri" wird da auf den aktuellen Stand gesetzt :)
Wenigstens wer, der drauf achtet :D
Andere Foren erziehen einen zu guter Grammatik & Rechtschreibung :) Beispielsweise tutorials.de ;)
ChristianFischer
25.09.2007, 17:35
portDispatch Wie man in den Wald ruft...
Ihr habt mich falsch verstanden, die Auth-Daten werden ordentlich in der Session gespeichert (wenn auch nicht so lange, wie ich es gerne hätte, hat jemand einen Tipp für eine Timeout-Einstellung?).
Theoretisches Beispiel:
Ich bin eingeloggt, editiere irgendwas und muss zu einem Meeting. In der Zwischenzeit läuft die Session ab. Als ich zurück an den Rechner komme, will ich noch speichern (absenden), bekomme aber nur die Login-Seite angezeigt.
Die Daten, die ich abgeschickt habe, sollten dann natürlich nicht verloren gehen, sondern müssten irgendwo (als versteckte Formularfelder auf der Login-Seite oder in der Session z.B.) zwischengespeichert werden.
Balu
ChristianFischer
25.09.2007, 17:47
Erhöh die Sessionlifetime in der Konfiguration deines Webservers wenn es länger leben soll.
KingCrunch
25.09.2007, 23:40
Stimmt, abers wird das net gehen. Andererseits: Vorher Speichern hält fit :D Man bedenke den Datenmüll, die du dir selber damit fabrizieren kannst, wenn du einfach mal alte Sessions rumfliegen lässt
DennisBecker
26.09.2007, 09:37
Es gibt auch en Firefox-Extension, die Formular-Werte zwischenspeichert - vielleicht wäre das eine Alternative? Dieses Thema wurde schon tausendfach diskutiert. Ich bin der Meinung, diese Funktion sollte nicht jede Webapplikation einzeln einbinden sondern der Browser sollte das von Haus aus unterstützen!
Es gibt auch en Firefox-Extension, die Formular-Werte zwischenspeichert - vielleicht wäre das eine Alternative? Dieses Thema wurde schon tausendfach diskutiert. Ich bin der Meinung, diese Funktion sollte nicht jede Webapplikation einzeln einbinden sondern der Browser sollte das von Haus aus unterstützen!
Es geht doch nicht ums Zwischenspeichern von Formularfeldern? Es geht darum, dass eine Session schon mal ablaufen kann, weil der Benutzer zwischendurch eine Stunde etwas anderes macht. Wenn er dann das Formular abschickt und nur noch eine Meldung bekommt: "Sie waren zu lange inaktiv und jetzt sehen Sie zu, dass Sie das lange Formular wieder eingegeben bekommen.", wird er sich nicht darüber freuen.
Das Stichwort hierzu heisst: Usability.
Darum möchte ich auch, dass sich der User auf jeder Seite anmelden kann. Dadurch kann er z.B. auch irgendeine Seite in der Applikation als Bookmark speichern oder von einem Kollegen eine URL geschickt bekommen, statt der Beschreibung "Einloggen, im Menü auf Obereintrag, dann auf Untereintrag, dann drei Seiten runterscrollen, den Eintrag auswählen und auf Bearbeiten klicken".
Besser ist: "Korrigier mal den Titel bei http://www.example.com/admin/stuff/edit/2332"...
Balu
PS: Abgesehen davon, dass ich von meinem Betriebssystem auch nicht verlange, dass es die Eingaben die ich in *Office gerade getätigt habe, zur Sicherheit speichert, falls das *Office mal wieder abstürzt.
DennisBecker
26.09.2007, 13:08
Wenn die Formularfelder zwischengespeichert werden, du dann später ausgeloggt wirst, da die Session abgelaufen ist und dich darauf hin einloggst und wieder zu dem Formular geht, dann schreibt die FF Extension die ursprünglich von dir eingegebenen Inhalte wieder rein. Das war meine Antwort auf deine oben skizzierte Problemstellung ;)
KingCrunch
26.09.2007, 13:45
PS: Abgesehen davon, dass ich von meinem Betriebssystem auch nicht verlange, dass es die Eingaben die ich in *Office gerade getätigt habe, zur Sicherheit speichert, falls das *Office mal wieder abstürzt.Tut es aber :DDarum möchte ich auch, dass sich der User auf jeder Seite anmelden kann. Dadurch kann er z.B. auch irgendeine Seite in der Applikation als Bookmark speichern oder von einem Kollegen eine URL geschickt bekommen, statt der Beschreibung "Einloggen, im Menü auf Obereintrag, dann auf Untereintrag, dann drei Seiten runterscrollen, den Eintrag auswählen und auf Bearbeiten klicken".Öhm ... geht doch trotzdem !? Anmelden, dann URL eintippen, egal auf welcher Seite. So mach ich das immer, wenn ich Links zu Seiten bekomme und sehe da keine aussergöhnliche Belastung drin.
Naja, Fakt ist: Eine veraltete Session ist Datenmüll. Wann eine Session veraltet ist, muss leider der Entwickler (Server-Betreiber) selbst bestimmen, weil das stark variiert. 15min für eine Session ist schon sehr lang. Ich weiß auch net, was ich davon halten soll, wenn jemand 1,5h an einem Beitrag schreibt :D
Als Konsens wäre meine Idee jetzt, dass die Webapplikation selbst eine Option bietet "Zwischenspeichern", so dass das Formular zwar abgeschickt wird, der Eintrag aber nicht am eigentlichen Bestimmungsort landet, sondern erstmal ... irgendwo :D
DennisBecker
26.09.2007, 13:54
Als Konsens wäre meine Idee jetzt, dass die Webapplikation selbst eine Option bietet "Zwischenspeichern", so dass das Formular zwar abgeschickt wird, der Eintrag aber nicht am eigentlichen Bestimmungsort landet, sondern erstmal ... irgendwo :D
Deshalb sage ich ja, warum müssen Millionen von Webapplikationen solch ein Feature auf biegen und brechen und meist schlecht als recht entwickeln, wenn es beim Browser sehr einfach ist, dieses Feature nachzurüsten / zu integrieren?
KingCrunch
26.09.2007, 14:04
Weil: Auf Browser-Ebene macht es mehr Sinn. Eine Session kann ja zB auch auslaufen, weil deine Internetverbindung getrennt wurde. Versuch ohne Internet mal was im Internet zu speichern :D Da is der Browser nunmal praktischer.
Diverse Forensoftware unterstützen sowas ähnliches ja auch im Sinne einer Notizzettel-Funktion im Benutzerpanel.
Tut es aber :D
Abstürzen ja :o, aber Dein Betriebssystem speichert doch nicht den Text, den Du gerade eingetippt hast? Klar gibt es Office-Pakete, die nach einem Absturz den Text wiederherstellen können, aber das macht das Office, nicht Dein Betriebssystem... - Also sollte es die Anwendung machen und nicht der Browser.
Ich habe ein bischen das Gefühl, dass Ihr keine Kunden habt ;). Klar ist so ein Feature wunderbar und ich habe auch ein Plugin, das Formulare zwischenspeichern und wieder einfügen kann, aber das was man so als Kunde kennt, hat das eher nicht. Abgesehen davon, dass die meisten Leute der Gattung Kunden noch mit IE5 oder sowas rumhampeln (müssen). :eek:
Solche Kunden fangen morgens an, einen Text zu schreiben, werden unterbrochen, machen nach zwei Stunden weiter, werden unterbrochen und merken Abends beim Schliessen der Anwendungen "Oh, den Text habe ich garnicht gespeichert...". Ich kenne genug Firmen, die haben Session-Timeouts von 10 Stunden oder mehr...
Und so Sachen wie "erst einloggen, dann Link aufrufen" ist vielleicht eine Vorgehensweise für uns Entwickler, aber für "Kunden"? Nene, mit dieser Gattung scheint Ihr echt nicht viel in Kontakt zu kommen... :rolleyes:
Balu (kundengeplagt)
PS: Das Forum hier macht das übrigens auch "richtig". Ich kann den Text editieren, mich in einem anderen Tab ausloggen und dann speichern. Dann fragt er mich nach dem Login und speichert anschliessend den Beitrag - ohne dass ich ihn irgendwo zwischenspeichern muss.
vBulletin® v3.6.12, Copyright ©2000-2010, Jelsoft Enterprises Ltd.