Мой процесс авторизации пользователя выглядит следующим образом.
Во время процесса входа функция запускает следующий код.
$token = sha1(microtime(true) . mt_rand(10000, 90000));
setcookie('auth', $token, $timeout);
Затем добавляет сгенерированный token
в таблицу базы данных сразу после столбца идентификатора пользователя.Кстати, и в $_SESSION
, и в $_COOKIE
хранится только значение $token
.
Существует другая функция с именем protect
, которая находится в верхней части каждой страницы и проверяет, существуют ли файлы cookie:
- сначала проверяет таблицу дБ на
$token
: если с этим токеном нет пользователя, выписывает - Затем проверяет
$_SERVER['HTTP_USER_AGENT']
, $_SERVER['REMOTE_ADDR']
с теми, которые хранятся в таблицах дБ.
Вопрос
Я чувствую, что это небезопасный способ, потому что, если злоумышленник использует тот же компьютер и тот же браузер, он может получить доступ, просто "скопировав-вставив" куки-файлы.Также $ _SERVER ['REMOTE_ADDR'] не всегда работает.
Как я могу сделать этот вход более безопасным?
Подробно
Вот функция защиты
public function protect() {
if (!isset($_SESSION)) {
session_start();
}
$data = array();
if (isset($_SESSION['auth'])) {
$stmt = $this->db->prepare("SELECT l.browser, l.ip, u.ban from log AS l, users AS u WHERE l.token =? AND u.id=l.user_id LIMIT 1") or die($this->db->error);
$stmt->bind_param("i", $_SESSION['auth']) or die($stmt->error);
$stmt->execute() or die($stmt->error);
$stmt->store_result();
if ($stmt->num_rows == 0) {
$this->signout();
}
$stmt->bind_result($data['browser'], $data['ip'], $data['ban']);
$stmt->fetch() or die($stmt->error);
$stmt->close() or die($stmt->error);
$this->validation->check("protection", $data);
} else {
if (!isset($_COOKIE['auth'])) {
header('Location:' . wsurl);
}
$stmt = $this->db->prepare("SELECT l.browser, l.timeout, l.ip, u.ban from log AS l, users AS u where l.token =? AND u.id=l.user_id LIMIT 1") or die($this->db->error);
$stmt->bind_param("s", $_COOKIE['auth']) or die($stmt->error);
$stmt->execute() or die($stmt->error);
$stmt->store_result();
if ($stmt->num_rows == 0) {
$this->signout();
}
$stmt->bind_result($data['browser'], $data['timeout'], $data['ip'], $data['ban']) or die($stmt->error);
$stmt->fetch() or die($stmt->error);
$this->validation->check("protection", $data);
session_regenerate_id();
$_SESSION['auth'] = $_COOKIE['auth'];
$stmt->close() or die($stmt->error);
}
}
И проверка проверяет это
if ($data['browser'] != md5($_SERVER['HTTP_USER_AGENT'])) {
$this->registration->signout();
}
if ($data['ban'] == 1) {
$this->registration->signout(false);
header('Location:' . wsurl . "?page=msg&id=34");
}
if ($data['ip'] != $this->common->getIP("long")) {
$this->registration->signout();
}
if (isset($data['timeout']) && !empty($data['timeout'])) {
if (($data['timeout'] - $this->common->getTime()) < 0) {
$this->registration->signout();
}
}