2016-04-11 22 views
2

私が達成する必要があるのは、管理者が指定したユーザーのセッションを削除してリロゴンを強制する可能性を持たせることです。これは、たとえばユーザーのアクセス許可が変更された場合などに便利です。どのように他のユーザーがそのデータにアクセスできるようにセッションとユーザーを一緒にバインドするのですか?cakePHP3の特定のユーザのセッションを削除するには?

私はデータベースセッションストアを使用しているので、データベースからレコードを削除すると強制的に再ログインが行われます。また、認証はAuthコンポーネントに基づいています。

$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"] 
     ]); 

とセッションストレージ:

は、ここに私の関連する設定の一部をである私が、私は、データベースの更新コードを配置する場所マークした下

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

。残念なことに、ログインが実行されると、セッションは「再検証」され、IDが変更されます。要するに、ログインアクションで行われた変更は、リダイレクト後は表示されません。

ログインアクション:貴重なコメントやピンポイントのおかげで@ndm

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

セッションが更新されているので、 '$ this-> Auth-> setUser()'を呼び出した後でセッションIDにアクセスすると動作するはずです。何を試してみましたか? – ndm

+0

私はあなたが言ったことを正確に試しました。上記のコードでは、(setUserの後に)コメントがある場所でデータベースの内容を変更しましたが、リダイレクトまたは新しいリクエストの後にオーバーライドされます。 – Antoniossss

+0

少し正確で、理想的には使用したコードを表示し、 "_gets overriden_"が正確に何を意味するのか_ _ _は_what_データで上書きされていますか? – ndm

答えて

0

ありがとう@ ndmさんのコメントありがとうございます。私は(おそらく)実行可能な解決策を見つけました。私はセッションデータセーブプロセスにいくつかのコードを注入しなければならなかった。これを行うために、私はコールバックの役割でカスタムSessionHandlerとPHPのCloasureを使用しました。

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; 
    } 
} 

、ログインアクション

 $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()); 
     } 

このようにセッションデータをDBにフラッシュされた後、DBのセッション行が更新されます。

特定のユーザーのすべてのセッションを照会し、必要に応じてそのユーザーのリロングを強制的に削除できます。コールバックはユーザのログイン時に一度だけ呼び出されますが、すべてのhttpリクエスト中にUPDATEクエリdbを最適化して回避するという目標もありました。(これも解決策だからですが、避けたかったですが)避けたいのですが