2012-01-18 2 views
15

Short

Работа с системой входа в систему и попытка реализовать функцию запоминания меня.Правильный способ использования функции «Запомнить меня» в PHP

Недавно я провел исследование по этому предмету, прочитал кучу статей, постов, рассказов, романов, сказок (называя их так, потому что некоторые из них не содержат даже 1 строки кода, просто нагрузок слов) о, печенье уязвимостей, таких как фиксация, угон ... и т.д.

и решили достичь следующих целей

  1. чтобы установить время задержки между попытками входа в систему (для предотвращения BruteForce атак) и ограничить кол попытки
  2. Чтобы восстановить идентификатор сеанса почти во всех операциях

Но Я действительно смущен своей главной проблемой: какой способ является правильным, для функции «помнить меня»? использовать файлы cookie/сеанс/базу данных?

И, пожалуйста, объясните вашу идею о коде. (Я не могу четко понимать без кода)

Подробное

В настоящее время мой код выглядит, что

Во время входа в Я использую следующие функции для установки куки и сессии

protected function validateUser($userid, $ckey=0, $rememmber=0) { 
    session_start(); 
    session_regenerate_id(true); //this is a security measure 
    $_SESSION['user_id'] = $userid; 
    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); 
    if (isset($remember) && $rememmber == 'on') { 
     setcookie("user_id", $_SESSION['user_id'], time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/"); 
     setcookie("user_key", sha1($ckey), time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/"); 
    } 
    return true; 
} 

Затем на защищенных страницах пользователей, проверяя user_id с помощью user_id, чтобы принести все важные данные о пользователе из БД

public function protect() { 
     session_start(); 

     /* Secure against Session Hijacking by checking user agent */ 
     if (isset($_SESSION['HTTP_USER_AGENT'])) { 
      if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) { 
       $this->signout(); 
       exit; 
      } 
     } 

// before we allow sessions, we need to check authentication key - ckey and ctime stored in database 

     /* If session not set, check for cookies set by Remember me */ 
     if (!isset($_SESSION['user_id'])) { 
      if (isset($_COOKIE['user_id']) && isset($_COOKIE['user_key'])) { 
       /* we double check cookie expiry time against stored in database */ 

       $cookie_user_id = $_COOKIE['user_id']; 
           $stmt = $this->db->prepare("select `ckey`,`ctime` from `users` where `id` =?") or die($this->db->error); 
      $stmt->bind_param("i", $cookie_user_id) or die(htmlspecialchars($stmt->error)); 
      $stmt->execute() or die(htmlspecialchars($stmt->error)); 
      $stmt->bind_result($ckey, $ctime) or die($stmt->error); 
      $stmt->close() or die(htmlspecialchars($stmt->error)); 
       // coookie expiry 
       if ((time() - $ctime) > 60 * 60 * 24 * COOKIE_TIME_OUT) { 
        $this->signout(); 
       } 
       /* Security check with untrusted cookies - dont trust value stored in cookie.  
        /* We also do authentication check of the `ckey` stored in cookie matches that stored in database during login */ 

       if (!empty($ckey) && is_numeric($_COOKIE['user_id']) && $_COOKIE['key'] == sha1($ckey)) { 
        session_regenerate_id(); //against session fixation attacks. 

        $_SESSION['user_id'] = $_COOKIE['user_id']; 
        $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); 
       } else { 
        $this->signout(); 
       } 
      } else { 
       if ($page != 'main') { 
        header('Location:' . wsurl); 
        exit(); 
       } 
      } 
     } 
+1

Просто комментарий: с точки зрения UX, я думаю, что это хороший момент, чтобы ваши пользователи узнали, имеете ли вы «держать меня в системе» или просто «помните мою личность». – PapaFreud

+0

Возможный дубликат: http://stackoverflow.com/questions/244882/what-is-the-best-way-to-implement-remember-me-for-a-website – ThinkingMonkey

+0

@ThinkingMonkey ok, you'r cool :) –

ответ

2

Но я действительно смутился о своей главной проблеме: какой путь является правильным, для функции «помнить меня»? использовать файлы cookie/сеанс/базу данных?

Http - это protocall без гражданства. Идентификатор аутентификации должен сохраняться, чтобы сохранить состояние. Правильный способ - использовать сеанс. Теперь, как вы отслеживаете сеанс? Тебе решать. Но файлы cookie неплохие.

В сеансе вы можете сохранить хэш, созданный из разных критериев браузера (пользовательский агент, os, разрешение экрана и т. Д.), Чтобы проверить, является ли токен из той же среды. Чем больше критериев вы сохраните, тем больше будет сложнее захватить. Btw вам нужен JavaScript, чтобы каждый раз получать дополнительную информацию.

+2

Я ненавижу downvoting, но 'попробуйте отправить его по URL-адресу (я знаю, он выглядит уродливым).' - действительно является целью для downvote. Это хорошо известно ** уязвимость при фиксации файлов cookie ** уязвимость –

3

Если вы хотите пример «запомнить меня» функции с кодом, вы можете проверить мой PHP библиотеку в https://github.com/gbirke/rememberme

+0

Я работал над firefox. Но на хроме ваши тестовые файлы не работают: остается на первой странице, не входит в систему. –

+0

Могу ли я забрать 5-10 минут? добавьте меня tural.teyyuboglu в skype –

8

Чтобы установить время задержки между попытками входа в систему (для предотвращения нападений с использованием bruteforce) и для ограничения количества попыток

Итак, вы предоставляете метод для DOS по счету?

Чтобы регенерировать идентификатор сессии почти на каждой операции

ERM, нет. На самом деле это может победить объект. Вы всегда должны генерировать новый идентификатор, когда текущий идентификатор истек или когда пользователь аутентифицирован - иначе оставьте его в покое.

Но я действительно смущен своей главной проблемой: какой путь является правильным, для функции «помнить меня»? использовать файлы cookie/сеанс/базу данных?

Поскольку вам нужно сохранить токен на клиенте, это означает, что файлы cookie (если только вы не хотите писать что-то действительно сложное с использованием локального хранилища). Поскольку вы не хотите показывать данные с помощью простой подстановки cookie/make, это означает, что это должно быть случайное значение.И для согласования сохраненного случайного значения это означает сохранение серверов данных - возможно, в базе данных, поскольку должно быть возможно ссылаться на данные на основе идентификатора пользователя или на основе случайного значения.

Хотя вы могли бы просто использовать не истекающий (или очень долгоживущий) сеанс, я бы держался подальше от этого - данные будут получать снежок - и рекомендуется обновлять данные сеанса время от времени.

Вы также должны учитывать сценарий, когда пользователь хочет, чтобы вы помнили ее на двух разных компьютерах. Если вы используете только один токен «запомнить меня» для каждой учетной записи, то либо вам придется использовать одно и то же значение у обоих клиентов, либо удалить старый токен при создании нового (т. Е. Пользователь может запоминаться только на одной машине).

, пожалуйста, объясните вашу идею по коду. Я не могу понять ясно без кода

№. Мне платят за код; Если вы хотите, чтобы я написал код для вас, вам нужно будет заплатить мне. И код займет гораздо больше места и времени, чем описание выше.

+3

+1 для объяснения, почему вы не написали код. –

+0

В этом сообществе мы пытаемся помочь друг другу. Я тоже разработчик. Просто хочу получить совет и пример кода вашей идеи, (я не английский, но не все ваши сообщения на 100% понятны мне) В любом случае, спасибо за то, что тратили свое время бесплатно :) –

Смежные вопросы