Предотвращать двойную порцию login

У меня есть недостаток с двойной порцией logueo. Я хочу, чтобы, когда пользователь будет logueado в браузере и будет хотеть loguearse с тем же счетом в другом браузере, этот не позволил это ему.

Как я могу осуществлять это в PHP?

Это мой код session:

$user_ip = $_SERVER['REMOTE_ADDR'];
$username = isset($_POST['usuario']) ? addslashes(trim($_POST['usuario'])) : '';
$password = isset($_POST['contrasenia']) ? addslashes(trim($_POST['contrasenia'])) : '';
$errors = array();
if(isset($_POST) && !empty($_POST)){
    // Validar nombre de usuario.
    $query = @mssql_query('SELECT UserID,Pw FROM  PS_UserData.dbo.Users_Master WHERE UserID = \'' . $username . '\'');
    if(empty($username)){
        $errors[] = 'Por favor, proporcione un nombre de usuario.';
    }else if(strlen($username) < 3 || strlen($username) > 16){
        $errors[] = 'Nombre de usuario debe tener entre 3 y 16 caracteres de longitud.';
    }else if(ctype_alnum($username) === false){
        //$errors[] = '';//Nombre de usuario debe consistir en números y letras únicamente.;
    }else if (mssql_num_rows($query) == 0){
        $errors[] = 'el usuario no existe';
    }
    // Validar la contraseña de usuario.
    $query2 = @mssql_query('SELECT UserID,Pw FROM  PS_UserData.dbo.Users_Master WHERE UserID = \'' . $username . '\' and PW = \'' . $password . '\'');
    if(empty($password)){
        $errors[] = 'Por favor ingrese su contraseña.';
    }else if(strlen($password) < 3 || strlen($password) > 16){
        $errors[] = 'La contraseña debe tener entre 3 y 16 caracteres de longitud.';
    }else if (mssql_num_rows($query2) == 0){
        $errors[] = 'Por favor, proporcione la contraseña correcta.';
    }
2
задан 14.10.2016, 11:01
5 ответов

Так как весь мир использует ответы, чтобы писать мнения без кода..., я не буду быть меньше, но я это сделаю внося код.

То, что я рекомендую тебе, состоит в том, чтобы ты не блокировал новую попытку начала сеанса, это произведет тебе больше проблем, чем преимуществ. Сконцентрируйся на том, чтобы отвергать тебе старый сеанс и позволять новость.

Как? Самое простое состоит в том, чтобы повторно использовать таблицу пользователей и добавлять поле "SID", в котором ты будешь хранить SID сеанса, который инициализировал сеанс.

ЗАМЕТЬ: Я буду использовать PDO, помни, что функции mssql_* они устаревшие и небезопасные.

Когда инициализировали сеанс и установив $_SESSION['UserID'] в подходящую стоимость ты сохраняешь стоимость SID в таблице пользователей в поле, которое ты создал для этой функции:

<?php
$consulta = $pdo->prepare('
  UPDATE PS_UserData.dbo.Users_Master
    SET SID = :SID
    WHERE UserID = :UserID
');
$consulta->execute([
  ':UserID' => $_SESSION['UserID'],
  ':ID' => SID,
]);

Сейчас, я участвую в рыцарском турнире, установив связь в базу данных и реализовав проверки безопасности, которую ты считал бы осуществленной (уровни доступа, и т.д.) ты будешь должен подтверждать, что SID совпадает:

<?php
$consulta = $pdo->prepare('
  SELECT SID
    FROM PS_UserData.dbo.Users_Master
    WHERE UserID = :UserID
');
$consulta->execute([
  ':UserID' => $_SESSION['UserID'],
]);
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
if ($resultado === FALSE) {
  die('Error: ¿¿Usuario no existente??');
}
if ($resultado['SID'] !== SID) {
  /* ¡Es una sesión antigua! Han iniciado sesión en otro equipo,
    invalidamos la información de la sesión actual y reenviamos
    al usuario a la página de entrada */
  unset($_SESSION);
  session_destroy();
  /* Opcionalmente podemos destruir la cookie de sesión */
  header('Location: entrada.php');
  exit();
}
/* A partir de aquí todo va bien, el usuario tiene únicamente
  una sesión activa */

Я надеюсь, что он ты помогает.

2
ответ дан 24.11.2019, 13:06
  • 1
    привет oscar, снова спасибо за Ваш repesta. – Jhoni Williands 15.10.2016, 03:57
  • 2
    относительно кода у меня есть один согрешите и # 241; или ошибка sintanxis в следующая линия $consulta-и gt; execute ([и #39;: UserID и # 39; = > $ _SESSION [и #39; UserID и # 39;], image.prntscr.com/image/2555500edf484b7c927a3c560a3c7f04.png , которым могло бы проистекать это? приветствие – Jhoni Williands 15.10.2016, 03:59
  • 3
    #191; Цюй и # 233; versi и # 243; n PHP ты используешь? Опора для определенных массивов используя квадратные скобки в и # 241; adi и # 243; в versi и # 243; n 5.4, если ты используешь versi и # 243; n предыдущая обязанность и # 237; схвати меняться " [...] " из-за " array (...) ". В этом случае я напоминаю тебе, что versi и # 243; n м и # 225; s старая, что остается с опорой, - 5.6, быть должным и # 237; схвати становиться отвечающее современным требованиям: php.net/supported-versions , хотя tambi и # 233; n podr и # 237; чтобы быть виной, которой твой редактор c и # 243; я говорю, что PHP был слишком старым. – OscarGarcia 16.10.2016, 08:17
  • 4
    это должен быть raz и # 243; n, из-за которой оно я не функционирует тогда, я использую PHP Версия 5.3.1 нуждался в том, чтобы реализовать некоторые я изменяю файлы conexi и # 243; n уже это последняя версия, которая выносит связь mssql_ этот недостаток, мне повернулся ночной кошмар – Jhoni Williands 16.10.2016, 09:41

Ты должен создавать колонну в таблице пользователя, где каждый ты видишь, что loguee хранился id сеанса, и каждый ты видишь, что была сделана одна peticiГіn, нужно проверять, что id сеанса встретился с хранением иначе, закрылся сеанс

0
ответ дан 24.11.2019, 13:06
  • 1
    Привет andres, спасибо за восполни запас, как podr и # 237; чтобы приносить в acabo этот м и # 233; все я звучит достаточно меткая для того, что я ищу реализовывать. – Jhoni Williands 14.10.2016, 18:36
  • 2
    Точно то, что я предложил, но перенеси проблемы, что он coment и # 233;..., если он теряет куки-файл sesi и # 243; n или он не закрывает sesi и # 243; n, потом не podr и # 225; открываться sesi и # 243; n в другой команде. – OscarGarcia 14.10.2016, 23:08
  • 3
    если podr и # 237; чтобы это инициализировать, если колонна, где хранится id sesi и # 243; n sobrescribe каждый раз, когда пользователь инициализируется sesi и # 243; n, это закрывает сеансы в других браузерах и поддерживает одинокий sesi и # 243; n включи из-за счета – Andres Castellanos 14.10.2016, 23:50

Другое решение состоит в том, чтобы использовать

localStorage

браузера, используя Javascript, чтобы хранить id sessión пользователя, если этот не существует в браузере, он будет значить, что он должен loggearse снова.

0
ответ дан 24.11.2019, 13:06
  • 1
    Это - точно то, что делает куки-файл sesi и # 243; n, хранить идентификацию sesi и # 243; n пользователя. – OscarGarcia 14.10.2016, 23:07

Новая таблица, в которой ты сохранял бы, когда пользователь инициализируется, и cerra сеанс. После того, как старались присоединять нового браузера, и если уже у него есть инициализировавший sessión, он отрицается. Но будет проблема в момент знания, когда он "действительно" закончил настоящий сеанс.

0
ответ дан 24.11.2019, 13:06

Я надеюсь, что это подает тебя, что в меня я функционирует, состоит в том, чтобы создавать field в базе данных, которая обновляет 1, когда пользователь будет инициализировать сеанс и обновит 0, когда он закроет сеанс

Таким образом, когда он скроллирует функцию login, он проверяет, что этот этот field в 0, и если это так, продвинулся с login и это обновил в 1, используя это, когда ты захочешь наставить сеанс в другом браузере, он столкнется тем, что у поля есть 1, и не продолжит, проблема, которая у меня была, пошла со временем жизни default куки-файла или сеанса, так как, если это так, когда закроется сеанс, он не обновит таблицу в 0, и ты не сможешь инициализировать сеанс снова.

Чтобы это решать используй настойчивые сеансы и куки-файл, который умирает в длинном времени

Пример:

База данных:

  • пойдите | 1
  • username | тест
  • password | 12345
  • loggedin | 0//, зарегистрировав в пользователя это, должно быть, 0 из-за default, этого добиваются, используя 'default', создав field в базе данных

Сейчас нужно получать стоимость этого поля используя query. Давайте предполагать, что переменная, распределенная этому полю после query - $loggedin

Внутри функции login только требуют IF:

if ($loggedin == 0){
  // Continuar con la funcion login y usar un 'UPDATE' para cambiar el valor de 0 a 1

}else{
 // redireccionar a index
}

В момент закрытия сеанса ты должен делать также 'UPDATE', чтобы менять стоимость от 1 до 0

Чтобы избегать того, чтобы сеанс умер, и никогда больше не моги соглашаться ты можешь проверять эти публикации:

Persistent sessions Куки-файл never умри

Я надеюсь, что оно ты функционирует Привет

0
ответ дан 24.11.2019, 13:06
  • 1
    Привет @HiramAngeles, ты можешь добавлять пример? bienvenid@ в SOes! – Alan 14.10.2016, 22:53
  • 2
    Если в пользу любого мотива ты теряешь куки-файл sesi и # 243; n (из-за бренности вслед за некоторыми d и # 237; схвати, из-за того, что отложи куки-файлы, и т.д.) пользователь оставаться и # 237; в блокированный. Хуже в и # 250; n, если dej и # 243; sesi и # 243; n открытая он делает один d и # 237; в, например, в работе пятница и захоти согласиться с дома s и # 225; bado вечером, tendr и # 225; который ждать в понедельник, чтобы ему мочь удаваться в работу и закрыть sesi и # 243; n. – OscarGarcia 14.10.2016, 23:05
  • 3
    Я заношу в список @Alan, надеюсь немного более ясный – Hiram Angeles 14.10.2016, 23:11
  • 4
    @OscarGarcia я соглашаюсь с тобой, он очень мало функциональный, так как ты только сможешь использовать устройство, где ты инициализировал сеанс, но это ответ, который пришел в голову начальному вопросу – Hiram Angeles 14.10.2016, 23:12
  • 5
    Проблема изменения и(или) подтверждения поля состоит в том, что могут случаться условия бега. Возможно производить случай, в котором могут открыться два сеанса (или м и # 225; s) одновременно. Храня SID мы гарантируем, что s и # 243; это одна из них быть и # 225; v и # 225; lida. – OscarGarcia 14.10.2016, 23:31