Reputation: 21
I'm currently facing the situation, that the ZendFramework2
ZFCuser-Module
does not have any options to prevent a user from logging in from two devices at the same time.
We recently had a case, that two people were "account-sharing" and accidentally deleted each others data. Since I did not build the application to account for this kind of resource conflicts, I need to prevent this behaviour now.
Is there any module or easy possibility out there to prevent account-sharing in Zend Framework 2 with ZFCUser
?
The docs and SO and all sorts of ZF2 blogs somehow appear to never have come across this type of problem...
Thanks in advance!
Upvotes: 2
Views: 435
Reputation: 631
I was able to achieve the functionality of limiting the number of sessions for the same user.
However, my solution (code below) doesn't provide any data-protected layer in order to restrict CRUD operation performed from another session.
I think you can achieve this if you restrict operation based on user_id and session_id
DB
id | user_id | client_id |
---|---|---|
00m5nqcvpk9bhqv7rbllq5hsi4 | 198 | 14 |
34ssnqcvpk9xxqv7rbll4354fdf | 123 | 42 |
id will be session_id (PHP SID)
Method
/**
*
* @param int $userId
* @param int $clientId
* @return type
*/
public function validateActiveSession($userId, $clientId) {
if (empty($userId)) {
$userId = $this->getResourceManager()->getIdentity()->getId();
}
if (empty($clientId)) {
$clientId = $this->getResourceManager()->getIdentity()->getClientId();
}
$sessionManager = $this->getServiceLocator()->get('Zend\Session\SessionManager');
$id = $sessionManager->getId();
$userModel = $this->getResourceManager()->getuserModel();
$sIdUserExist = $userModel->getUserActiveSession('', '', $id);
if (empty($sIdUserExist)) {
$userModel->addUserSessionBySidAndUserClientId($id, $userId, $clientId);
}
}
Repository
public function addUserSessionBySidAndUserClientId($sessionId, $userId, $clientId)
{
$em = $this->_em->getConnection();
$sql = "INSERT INTO `user_session`(`id`, `user_id`, `client_id`) VALUES (:id,:user_id,:client_id)";
$params = array('id' => $sessionId, 'user_id' => $userId, 'client_id' => $clientId);
$stmt = $em->prepare($sql);
return $stmt->execute($params);
}
public function getActiveUserSession($userId, $clientId, $sessionId)
{
$rsm = new ResultSetMapping();
$rsm->addScalarResult('id', 'id');
$rsm->addScalarResult('user_id', 'user_id');
$userIdClause = $clientIdClause = $andClause = $sessionIdClause = '';
if (!empty($userId)) {
$userIdClause = 'user_id = :user_id';
}
if (!empty($clientId)) {
$clientIdClause = ' and client_id = :client_id';
}
if (!empty($userId) && !empty($sessionId)) {
$andClause = ' and ';
}
if (!empty($sessionId)) {
$sessionIdClause = 'id = :id';
}
$query = $this->_em->createNativeQuery('SELECT id,user_id FROM user_session WHERE ' . $userIdClause . $clientIdClause . $andClause . $sessionIdClause, $rsm);
if (!empty($userId)) {
$query->setParameter('user_id', $userId);
}
if (!empty($clientId)) {
$query->setParameter('client_id', $clientId);
}
if (!empty($sessionId)) {
$query->setParameter('id', $sessionId);
}
return $query->getResult();
}
once user logged-in check for active sessions
$sameActiveUser = count($userModel->getActiveUserSession($userId, $clientId, ''));
if ($sameActiveUser == 2) { //already 2 active session than restrict 3rd
return "session already present";
} else {
$this->validateActiveSession($userId, $clientId);
}
Upvotes: 0