2016-04-11 3 views
2

Was ich erreichen muss, ist die Möglichkeit für den Administrator, die Sitzung eines bestimmten Benutzers zu entfernen, um eine erneute Anmeldung zu erzwingen. Dies kann nützlich sein, wenn sich beispielsweise Benutzerberechtigungen ändern. Wie binden Sie Sitzung und Benutzer zusammen, damit andere Benutzer auf diese Daten zugreifen können?So löschen Sie die Sitzung für einen bestimmten Benutzer in CakePHP3?

Ich verwende den Datenbanksitzungsspeicher, so dass das Entfernen eines Datensatzes aus der Datenbank zu einem erneuten Erzwingen der Anmeldung führen würde. Auch die Authentifizierung basiert auf Auth Komponente.

Hier einige meiner verwandten config:

$this->loadComponent('Auth', [ 
      'loginAction' => [ 
       'controller' => 'Auth', 
       'action' => 'login' 
      ], 
      'loginRedirect' => "/home", 
      'logoutRedirect' => [ 
       'controller' => 'Auth', 
       'action' => 'login' 
      ], 

      'authError' => "You have no permissions to access resource ${url}. Contact system administrator.", 
      'storage' => 'Session', 
      'authenticate' => [ 
       'Form' => [ 
        'userModel' => 'User', 
        'finder' => 'user', 
        'fields' => ['username' => 'name', 'password' => 'password'] 
       ] 
      ], 
      'authorize' => ["Controller"] 
     ]); 

und Sitzungsspeicher:

'Session' => [ 
     'defaults' => 'database', 
] 

Unten habe ich markiert haben, wo ich Datenbank-Update-Code platzieren würde. Leider wird die Sitzung nach der Ausführung des Logs "revalidiert", so dass sich die ID ändert. Alles in allem sind Änderungen in der Login-Aktion nach der Weiterleitung nicht sichtbar.

Anmeldung Aktion:

public function login() 
{ 
    $form = new LoginForm(); 
    if ($this->request->is('post')) { 
     if ($form->validate($this->request->data)) { 
      $user = $this->Auth->identify(); 
      if ($user) { 
       $this->Auth->setUser($user); 
       // here would be good place to update the database 
       return $this->redirect($this->Auth->redirectUrl()); 
      } else { 
       $this->Flash->error("Invalid security credentials provided"); 
      } 
     } else { 
      $this->Flash->error("Invalid login form"); 
     } 
    } 
    $this->set('loginForm', $form); 
} 
+0

Die Sitzung wird erneuert, wenn die Auth-Komponente in den Sitzungsspeicher schreibt. Der Zugriff auf die Sitzungs-ID nach dem Aufruf von '$ this-> Auth-> setUser()' sollte also funktionieren. Was genau hast du probiert? – ndm

+0

Ich habe genau das versucht, was Sie erwähnt haben. Im Code oben habe ich den Datenbankinhalt an der Stelle geändert, an der der Kommentar steht (nach setUser), aber diese wird nach der Umleitung oder der neuen Anfrage immer noch überschrieben. – Antoniossss

+0

Sie müssen ein wenig genauer sein, idealerweise den Code, den Sie benutzt haben, und erklären was genau "_gets overriden_" bedeutet, _where_ wird _what_ mit _what_ überschrieben? – ndm

Antwort

0

@ndm Dank für wertvolle Kommentare und Genauigkeiten.

Dank @ ndms Anmerkungen habe ich (höchstwahrscheinlich) eine brauchbare Lösung gefunden. Ich musste Code in den Sitzungsdatenspeicherungsprozess einfügen. Um dies zu tun, habe ich benutzerdefinierte SessionHandler und PHP Cloasure in der Rolle des Rückrufs verwendet.

class UserSession extends DatabaseSession 
{ 
    public $callback; 
    public function write($id, $data) 
    { 
     $result = parent::write($id, $data); 
     if ($this->callback) { 
      call_user_func($this->callback,$id); 
     } 
     return $result; 
    } 
} 

und die Login-Aktion

 $user = $this->Auth->identify(); 
     if ($user) { 
      $this->Auth->setUser($user); 
      /** @var UserTable $model */ 
      $model = $this->loadModel("User"); 
      $handler = $this->Session->engine(); 
      /** @var UserSession $handler */ 
      $handler->callback = function ($id) use ($model, $user) { 
       $model->updateSession($id, $user['id']); 
      }; 
      return $this->redirect($this->Auth->redirectUrl()); 
     } 

Auf diese Weise wird die Sitzung Zeile in der DB AFTER Sitzungsdaten aktualisiert werden, in die DB gespült.

Jetzt kann ich alle Sitzungen für bestimmte Benutzer abfragen und sie bei Bedarf erzwingen, die erneute Anmeldung für diesen Benutzer erzwingen. Callback wird nur einmal nach Benutzeranmeldung aufgerufen, was auch mein Ziel bei der Optimierung und Vermeidung von UPDATE Query db während jeder http Anfrage war (weil das auch die Lösung wäre, aber das wollte ich vermeiden)