我的用户授权过程就是这样。
在登录过程中,函数会触发代码。
$token = sha1(microtime(true) . mt_rand(10000, 90000));
setcookie('auth', $token, $timeout);
然后在用户id列之后立即将生成的token
添加到数据库表中。 BTW,$_SESSION
和$_COOKIE
只存储$token
值。
另一个名为protect
的函数位于每个页面的顶部,并检查是否存在cookie:
$token
:如果没有这个用户
令牌,签出$_SERVER['HTTP_USER_AGENT']
,$_SERVER['REMOTE_ADDR']
。我觉得这不是安全的方式,因为如果攻击者使用相同的PC和相同的浏览器,只需通过“复制粘贴”cookie即可访问。另外$ _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();
}
}
答案 0 :(得分:4)
在不影响应用程序可用性的情况下,您无能为力。例如,您可以使用用户IP,用户代理或用户提供的环境变量的混合作为令牌的盐,但如果用户IP已更改或任何环境变量(不一定是静态的),则不会再次登录。
老实说,这不是您应该担心的安全问题,这是用户的责任。如果有人可以使用他们的计算机并复制他们的cookie,他们可能会采取额外的步骤直接提取他们的密码(如果他们使用Firefox,则很容易..)。
答案 1 :(得分:1)
我可能误解了 - 但是可以窃取cookie的攻击者可以通过创建cookie并将HTTP_USER_AGENT, REMOTE_ADDR
元素添加到被盗令牌来窃取会话。
我会设置令牌,并拥有一个带
的数据库表TOKEN REMOTE_ADDR HTTP_USER_AGENT
------------------------------------
列。您的protect()方法应检查令牌,然后将当前用户的远程地址和用户代理与数据库进行比较。
这样,可以窃取你的cookie的攻击者也必须能够模仿你的浏览器(琐碎的)和IP地址(更难,但仍然可以)。
另外,请检查this question。