예를 들어서 동시에 같은 컴퓨터의 다른 브라우저에서 같은 아이디로 로그인 하거나, 다른 컴퓨터에서 같은 아이디로 로그인 하는 경우.
방법은 여러가지가 있지만 가장 간단하게 내가 처리한 방법은 토큰을 발행해서 디비와 세션에 저장한 후, 그 둘을 비교해서 일치하지 않는 경우에는 이전에 로그인 한 사용자 세션을 끊어버리는 방법이다.
즉 로그인 한 사용자가 있는데 다른 사용자가 로그인 한 경우에 디비의 토큰값이 변하므로 세션에 가지고 있는 토큰과 디비에 저장되어 있는 토큰이 다르게 되므로 그 경우에 세션 삭제하고 로그아웃 시켜버렸다.
단점이라면 매번 페이지 열 때마다 체크를 해 줘야 한다는 점...cakephp3에서는 beforeFilter() 를 이용하면 모든 페이지에 적용하지 않아도 자동으로 페이지 로딩하면서 실행을 해 준다.
주석 일본어로 달았는데 뭐 아무도 안 볼테니 ㅋㅋㅋㅋ
> 소스코드 보기
|
$query = $this->Users->find()->where(
['account' => $this->request->data['account'],
'customer_no' => $this->request->data['customer_no']
]);
$targetUser = $query->first();
$this->Users->initUser($targetUser);
$user = $this->Auth->identify();
if ($user)
{
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$account = $this->Auth->User('account');
$customer_idx = $this->Auth->User('customer_idx');
$query = $this->Users->query();
$query->update()
->set(['token' => null,
'modifier' => $account,
'modified' => Time::now()])
->where(['customer_idx' => $customer_idx, 'account' => $account])
->execute();
$this->request->session()->destroy();
$this->Flash->success(__('成功的にログアウトしました。'));
return $this->redirect($this->Auth->logout());
public function initUser($targetUser)
{
$token = hash('sha256', date("YmdHis").$_REQUEST['customer_no']);
$target->token = $token;
$this->save($targetUser);
}
public function beforeFilter(Event $event)
{
$session_token = $this->Auth->user('token');
if(isset($session_token))
{
$account = $this->Auth->user('account');
$customer_idx = $this->Auth->user('customer_idx');
$query = $this->Users->find()->where(
['account' => $account,
'customer_idx' => $customer_idx
]);
$user = $query->first();
$db_token = $user->token;
if($session_token != $db_token)
{
$this->Session->destroy();
$this->Flash->warning(__('トークン価が更新されましたのでログアウトされました。'));
$this->redirect($this->Auth->logout());
}
}
}
|
열심히 보는중
답글삭제