Empfehlungen: Erweiterte Suche

Gelöst: Einloggen/Ausloggen loginStatus speichern

Daten auslesen, verarbeiten und den Views übergeben

Gelöst: Einloggen/Ausloggen loginStatus speichern

Beitragvon enigmartin » So 27. Mär 2011, 10:54

Hallo, mein Name ist Martin und ich arbeite seit einigen Wochen / Monaten mit CakePHP. Wobei man es leider noch kein Arbeiten nennen kann. Ich bin dabei eine Seite zu bauen und stoße immer wieder auf Probleme.

Ich würde gerne beim ein- und ausloggen eines Benutzer den loginStatus (Tabellenname in der Datenbank) in der Datenbank ändern. Logt sich ein Benutzer ein so wird der loginStatus, von typ boolean/tinyint auf true/1 gesetzt. Loggt sich ein Benutzer wieder aus, so soll er logischerweise wieder auf false/0 gesetzt werden.

Ich habe es mit allen möglichen Methoden versucht aber es leider nicht geschafft. Wie ich vermute ist es das größte Problem das beim Login die id des Users nicht abrufbar ist. Daher habe ich irgendwie versucht den Benutzernamen zu verwenden um nur für den Benutzer der sich gerade anmeldet den status auf login zu setzen.

In einer Datenbank-Abfrage müsste das vereinfacht quasi so aussehen:

Code: Alles auswählen
UPDATE users SET loginStatus = '1' WHERE username = 'enigmartin';


Kann mir da jemand helfen? Ich habe ohnehin Schwierigkeiten spezielle Dinge mit CakePHP umzusetzen.

Grundsätzlich gefällt mir das Framework sehr aber bisher scheint es mir zu unflexibel. Vielleicht weiß ich einfach noch nicht wie ich es flexibler nutzen kann. Ich will keine Vorurteile aussprechen. Ich lasse mich gerne eines besseren belehren.

Vielen Danke für die Hilfe im vorraus.

PS: Bevor sich jemand aufregt. Ich habe das ganze auch schon in der deutschen CakePHP Google Group geschrieben aber ich sehe dort nicht durch und bin auch kein großer Fan von Google Groups.
Zuletzt geändert von enigmartin am So 27. Mär 2011, 22:11, insgesamt 1-mal geändert.
Benutzeravatar
enigmartin
 
Beiträge: 40
Registriert: So 27. Mär 2011, 10:42
CakePHP-Version: 1.3.8
OS: Windows 7

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon mbrod » So 27. Mär 2011, 13:05

Ich gebe mal einen vereinfachten Code wieder, so wie ich ihn benutze:
Code: Alles auswählen
function login(){
    if ($this->Auth->user()) {
        $this->User->id=$this->Auth->user('id');
        $now=date('Y-m-d H:i:s');
        $this->User->saveField('lastlogin',$now);
    }
}
 

Analog wie ich 'lastlogin' in die Datenbank schreibe, sollte auch ein 'loginStatus' abspeicherbar sein.
mbrod
 
Beiträge: 199
Registriert: Mi 20. Mai 2009, 18:09
Wohnort: Frankfurt am Main
CakePHP-Version: 1.3.8
OS: Mac OS X

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon Mathias » So 27. Mär 2011, 13:39

mbrod hat geschrieben:Ich gebe mal einen vereinfachten Code wieder, so wie ich ihn benutze:

Bedenke, dass du Auth für Authentifizierung nutzt.

@Martin: Wie oben schon erwähnt, würde ich 'Auth' benutzen. Somit kannst du dann zum Beispiel im Controller angeben, welche Funktionen mit oder ohne Authenfizierung genutzt werden dürfen. Auth ist aber kein Rechtesystem.
cheers
Benutzeravatar
Mathias
 
Beiträge: 225
Registriert: Mi 4. Jun 2008, 22:30
Wohnort: Berlin
CakePHP-Version: 1.3.x
OS: OS X 10.6.x

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon enigmartin » So 27. Mär 2011, 15:12

Erstmal vielen Dank für die schnellen Antworten.

So in etwa habe ich das auch versucht, nur nicht mit der Abfrage if( $this->Auth->user() ). Das leuchtet mir jetzt aber ein. Sonst wurde der Status zwar gespeichert aber immer wenn ich den login aufrufe. Nun wird der Status aber gar nicht gespeichert. Da ich aber auch den lastLogin speichern will konnte ich den Code von mbrod direkt übernehmen, musste nur den Tabellennamen ändern. Es wird aber dennoch nichts gespeichert. Nichtmal wenn ich nur den lastLogin speichern möchte.

So sieht es jetzt bei mir aus:

Code: Alles auswählen
function login()
{
    if( $this->Auth->user() )
    {
        $this->User->id = $this->Auth->user('id');
        $this->User->saveField('lastLogin', date('Y-m-d H:i:s'));
        $this->User->saveField('loginStatus', '1');
    }
}

Ich habe bei loginStatus auch schon als Wert true bzw. 1 ohne einfache Anführungszeichen verwendet aber da passiert leider auch nichts.

Ich vermute das die Auth-Informationen beim Login bzw. beim Abspeichern der Daten noch nicht vorhanden sind. Also das ich bei der SQL-Anweisung noch gar nicht sagen kann um welchen Benutzer es sich handelt.

Die Auth-Komponente nutze ich tatsächlig und ich weiß auch halbwegs das Auth nicht unbedingt was mit der ACL zu tun hat. So ganz verstehe ich das System aber noch nicht, da ich auch das erste mal mit ACL arbeite. Die ACL will ich aber erst einbauen wenn ich meine Interaktionen perfektioniert habe.

Was ich schon schaffe ist die einzelnen Datensätze, die nach dem Login angelegt werden können, mit der jeweiligen user_id abzuspeichern und auch für die Datensätze einen inProgress zu speichern. Also inProgress = true, wenn ein Datensatz geöffnet wurde und wieder auf false wenn er geschlossen wurde. Das Ganze soll verhindern das später zwei Benutzer gleichzeitig an einem Datensatz arbeiten und die nur Änderungen des letzten Speicherns übernommen werden. Da ist das aber nicht das Problem, da der Benutzer ja schon eingeloggt ist und ich auf die aktiven Benutzerdaten zugreifen kann.

Sieht dann so aus:

Code: Alles auswählen
function edit($id = null) {
    $this->User->updateAll(
        array('User.inProgress' => 1 ),
        array('User.id =' => $id )
    );
    if (!$id && empty($this->data)) {
        $this->Session->setFlash(__('Invalid user', true));
        $this->redirect(array('action' => 'index'));
    }
    if (!empty($this->data)) {
        $this->data['User']['inProgress'] = 0;
        if ($this->User->save($this->data)) {
            $this->Session->setFlash(__('The user has been saved', true));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
        }
    }
    if (empty($this->data)) {
        $this->data = $this->User->read(null, $id);
    }
    $groups = $this->User->Groups->find('list');
    $this->set(compact('groups'));
}
 


Also, wie gesagt, ich vermute das $this->Auth->user() beim Login noch gar nicht verhanden ist, das ich da was auslesen könnte.
Benutzeravatar
enigmartin
 
Beiträge: 40
Registriert: So 27. Mär 2011, 10:42
CakePHP-Version: 1.3.8
OS: Windows 7

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon enigmartin » So 27. Mär 2011, 15:18

Ich hab es jetzt auch folgendermaßen probiert:

Code: Alles auswählen
function login()
{
    if( $this->Auth->user() )
    {
        $this->User->id = $this->Auth->user('id');
        $this->User->updateAll(
            array('User.lastLogin' => date('Y-m-d H:i:s') ),
            array('User.loginStatus' => true )
        );
    }
}
 

oser so:

Code: Alles auswählen
function login()
{
    if( $this->Auth->user() )
    {
        $this->User->updateAll(
            array('User.lastLogin' => date('Y-m-d H:i:s') ),
            array('User.loginStatus' => true ),
            array('User.id' => $this->Auth->user('id') )
        );
    }
}
 

Beides gibt mit ebenfalls keinen Erfolg.
Benutzeravatar
enigmartin
 
Beiträge: 40
Registriert: So 27. Mär 2011, 10:42
CakePHP-Version: 1.3.8
OS: Windows 7

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon Mathias » So 27. Mär 2011, 15:31

So sieht es bei mir aus:
Code: Alles auswählen
    function login() {
        if ($this->Auth->user()) {
            if (!empty($this->data)) {
                if ($this->User->updateAll(array('last_login' => 'NOW()'), array('username' => $this->data['User']['username']))){
                    $this->Session->setFlash(__('Logged in', true), 'default', array('class' => 'success'));
                    $this->redirect(array('controller' => 'users', 'action' => 'view'));
                }
            }
        }  
    }
   


Wie gesagt, du brauchst den Login Status nicht speichern. Du hast ja Auth dafür.

Wie sehen denn die MySQL-Abfragen aus? Debug-Modus 2 sollte dir da weiterhelfen.
cheers
Benutzeravatar
Mathias
 
Beiträge: 225
Registriert: Mi 4. Jun 2008, 22:30
Wohnort: Berlin
CakePHP-Version: 1.3.x
OS: OS X 10.6.x

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon enigmartin » So 27. Mär 2011, 16:16

Danke Mathias aber das funktioniert leider auch nicht. Vielleicht habe ich Auth auch irgendwie falsch konfiguriert. Nun sieht es bei mir wie folgt aus:

Code: Alles auswählen
function login()
{
    if( $this->Auth->user() )
    {
        if( !empty( $this->data ) )
        {
            if( $this->User->updateAll(
                array('lastLogin' => 'NOW()'),
                array('username' => $this->data['User']['username'])
            ) )
            {
                $this->Session->setFlash( __('Logged in', true) );
                $this->redirect( array( 'controller' => 'users', 'action' => 'index' ) );
            }
        }
    }
}
 

So ziemlich das selbe wie bei dir.

Ich hab nun auch vermutet das es an dem standardmäßigem redirect im AppController liegt. Dort hatte ich im beforeFilter() folgendes zu stehen:

Code: Alles auswählen
$this->Auth->authError = 'Please login to view that page.';
$this->Auth->loginError = 'Incorrect username/password combination.';
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'index' );
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login' );


Das habe ich alles auskommentiert um das dann direct in der login-Methode des UsersController zu setzen. Da aber sogar der redirect nicht funktioniert vermute ich das beim login gar nicht die if-Abfragen besucht werden. Ich habe zum testen mal ein die() an jede Stelle gesetzt. Außerhalb jeglicher Abfrage greift das die(). Aber schon innerhalb von if( $this->Auth->user() ) greift es nicht mehr. Das ist der Beweis das if( $this->Auth->user() ) kein true erhält.

Funktioniert es denn mit Sicherheit bei euch?

Mathias hat geschrieben:Wie gesagt, du brauchst den Login Status nicht speichern. Du hast ja Auth dafür.


Wie meinst du das. Wird der loginStatus automatisch gespeichert wenn ich dem einen bestimmten Namen in der Datenbank gebe? Wie bei created und modified?

Mathias hat geschrieben:Wie sehen denn die MySQL-Abfragen aus? Debug-Modus 2 sollte dir da weiterhelfen.


Debug-Modus ist auf 2 und die Datenbank abfrage nach dem login ist leer (redirect auf Startseite => page_controller.php => home). Nur wenn ich die if-Abfragen entferne bekomme ich, logischer schon beim aufrufen des logins, eine SQL-Anweisung die wie folgt aussieht:

Code: Alles auswählen
UPDATE `users` AS `User` LEFT JOIN `groups` AS `Groups` ON (`User`.`groups_id` = `Groups`.`id`) SET `User`.`lastLogin` = NOW() WHERE `username` IS NULL


Daher kann ich sicher sein das der Username nicht verfgübar ist. Ist klar, ich habe ja auch nichts gesendet und $this->data ist leer. Wenn ich mich nun aber einlogge ist die SQL-Abfrage leer.
Benutzeravatar
enigmartin
 
Beiträge: 40
Registriert: So 27. Mär 2011, 10:42
CakePHP-Version: 1.3.8
OS: Windows 7

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon Mathias » So 27. Mär 2011, 16:41

Hast du im app_controller auch die components hinzugefügt?
Code: Alles auswählen
var $components = array('Auth', 'Cookie', 'Email', 'RequestHandler', 'Session');

Da sind noch ein paar andere, die ich sonst auch immer verwende.

Hier mal meine login.ctp
Code: Alles auswählen
<?php
    echo $form->create('User');
        echo $form->input('username', array('label' => __('Username', true)));
        echo $form->input('password', array('label' => __('Password', true)));
    echo $form->end(__('Login' ,true));
?>


Auth speichert die Informationen in der Session. Ist der User eingeloggt, ist zum Beispiel der Benutzername mit
Code: Alles auswählen
$session->check('Auth.User.username')
abrufbar. Solltest du nicht eingeloggt sein, ist dort auch kein Eintrag.
Heißt also, du brauchst keinen Status speichern.
cheers
Benutzeravatar
Mathias
 
Beiträge: 225
Registriert: Mi 4. Jun 2008, 22:30
Wohnort: Berlin
CakePHP-Version: 1.3.x
OS: OS X 10.6.x

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon enigmartin » So 27. Mär 2011, 17:17

Mathias hat geschrieben:Hast du im app_controller auch die components hinzugefügt?
Code: Alles auswählen
var $components = array('Auth', 'Cookie', 'Email', 'RequestHandler', 'Session');

Ja, ich hab die entsprechenden Komponenten geladen. Ich denke Auth und Session sollte genügen. Ich habe nun zwar auch Cookie und RequestHandler hinzugefügt aber es funktioniert immernoch nicht.

Mathias hat geschrieben:Auth speichert die Informationen in der Session. Ist der User eingeloggt, ist zum Beispiel der Benutzername mit
Code: Alles auswählen
$session->check('Auth.User.username')
abrufbar. Solltest du nicht eingeloggt sein, ist dort auch kein Eintrag.
Heißt also, du brauchst keinen Status speichern.


Ich habe nun folgendes in die default.ctp von layouts hinzugefügt:

Code: Alles auswählen
<?php echo '<pre>'; echo $session->check('Auth.User.username'); echo '</pre>'; ?>

Dadurch wird mir nach dem login ledglich eine 1 angezeigt, nicht aber der Benutzername. Die eins bedeutet wenn denn true, ist aber nicht die id des benutzers, da ich mich mit einem zweiten Benutzer angemeldet habe und erneut eine 1 angezeigt bekomme.

Den Status möchte ich nicht speichern um einen Beweis zu haben eingeloggt zu sein, sondern um später alle eingeloggten Benutzer anzeigen zu können, ala:

Code: Alles auswählen
SELECT * FROM users WHERE loginStatus = 1

Ich habe außerdem folgende Methode im AppController, die mir den Usernamen ausliest:

Code: Alles auswählen
function _usersUsername()
{
    $users_username = null;
    if( $this->Auth->user() )
    {
        $users_username = $this->Auth->user('username');
    }
    return $users_username;
}

und gebe diesen Wert dann über den beforeFilter an die views weiter:

Code: Alles auswählen
$this->set('users_username', $this->_usersUsername());


Gibt es da nicht irgendwie eine Möglichkeit das ganze auch an den Controller weiterzugeben?

Ich weiß sonst echt nicht mehr weiter. Das kann doch nicht so schwer sein. Zumindest die Post-Daten müssten ja im $this->data vorhanden sein, aber dieser ist ja auch leer, wie es scheint.

Ich habe das ganze in einem selbst programmierten Projekt so umgesetzt. Ich frage den Benutzernamen anhand des Post-arrays ab und ändere damit die Daten:

Code: Alles auswählen
UPDATE user SET loginStatus = true, loginDate = '" . time() . "' WHERE username = '" . $_POST['username'] . "'"

Wie gesagt, $this->data ist leer, wahrscheinlich wegen der Umleitung, und $this->Auth->user() ist bestimmt erst gefüllt nachdem meine Anweisungen in der login-Methode durchlaufen werden. Daher sind die Daten dann leer und keine Aktion in der login-Methode werden aufgerufen.

Ich weiß leider nicht weiter. Ich probiere und probiere aber nichts funktioniert. Ich habe sogar statisch angeben welcher User bearbeitet werden soll, sodas die WHERE-Klausel des SQL-Statements stimmen muss, nichts.

:(
Benutzeravatar
enigmartin
 
Beiträge: 40
Registriert: So 27. Mär 2011, 10:42
CakePHP-Version: 1.3.8
OS: Windows 7

Re: Einloggen/Ausloggen loginStatus speichern

Beitragvon enigmartin » So 27. Mär 2011, 22:07

Ich hab es jetzt endlich zum Laufen bekommen und will es euch und denen nach mir natürlich nicht vorenthalten.

Wie ich also schon vermutet habe liegt es an dem automatischen Redirect der Auth-Komponente. Diesen kurzerhand mit folgendem Code im beforeFilter() meines UsersControllers ausgeschaltet:

Code: Alles auswählen
function beforeFilter()
{
    parent::beforeFilter();
    $this->Auth->allow('register');
    $this->Auth->autoRedirect = false;
}

und schon klappt die ganze Misere.

Meine login-Methode:

Code: Alles auswählen
function login()
{
    if( $this->Auth->user() )
    {
        $this->User->id = $this->Auth->user('id');
        $this->User->saveField('lastLogin', date('Y-m-d H:i:s'));
        $this->User->saveField('loginStatus', 1);
        $this->Session->setFlash( __('Logged in', true) );
        $this->redirect( array( 'controller' => 'users', 'action' => 'index' ) );
    }
}

Warum kein if( $this->data )? Ich gehe da mal logisch ran. Erst wenn ich mich eingeloggt habe ist $this->Auth->user('id') vorhanden. Das heißt nachdem ich frage ob $this->Auth->user() vorhanden ist wird nichts mehr gesendet, demnach ist auch $this->data doch nicht vorhanden oder? Aber $this->Auth->user() ist vorhanden und kann auch abgefragt werden.

Meine logout Methode:

Code: Alles auswählen
function logout()
{
    if( $this->Auth->user() )
    {
        $this->User->id = $this->Auth->user('id');
        $this->User->saveField('loginStatus', 0);
        $this->Session->setFlash( __('Logged out', true) );
        $this->redirect( $this->Auth->logout() );
    }
}

Da hier $this->data eh nicht vorhanden ist, da ja nichts gesendet wird (gehe ich von aus), brauche ich das hier auch nicht abfragen, oder?

Wenn ich einen Denkfehler in meiner These habe dann bitte ich euch mich darauf hinzuweisen. Ansonsten ist das Problem hiermit behoben bzw. gelöst.

Und danke nochmal an mbrod und Mathias. Bis zum nächsten Mal. ;-)
Benutzeravatar
enigmartin
 
Beiträge: 40
Registriert: So 27. Mär 2011, 10:42
CakePHP-Version: 1.3.8
OS: Windows 7

Nächste

Zurück zu Controller

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron