如何有效地删除用户作为管理员

时间:2018-12-02 19:09:40

标签: php html session-cookies

当用户登录或注册时,我会存储一个会话和cookie,并在数据库中插入一些详细信息。

login / register.php

$_SESSION['userid'] = $userid;
$selector = base64_encode(random_bytes(9));
$authenticator = random_bytes(33);
$token = hash('sha256', $authenticator);
$expires = date('Y-m-d\TH:i:s', time() + 864000);
$stmt2 = $pdo->prepare("INSERT INTO auth_tokens 
(selector,token,userid,expires) VALUES (:selector, :token, :userid, 
:expires)");
$stmt2->bindParam(':selector', $selector);
$stmt2->bindParam(':token', $token);
$stmt2->bindParam(':userid', $userid);
$stmt2->bindParam(':expires', $expires);
$stmt2->execute();

setcookie(
    'remember',
     $selector.':'.base64_encode($authenticator),
     time()+(86400 * 90),
     '/',
     false
);

现在,当用户单击注销时,我破坏了会话和cookie

logout.php

session_start();
$_SESSION = array();
unset($_SESSION);
if (isset($_COOKIE['remember'])) {
unset($_COOKIE['remember']);
setcookie('remember', '', time() - 3600, '/'); // empty value and old 
timestamp
}
session_destroy();

作为管理员,我想从自己的终端删除用户时删除用户会话和cookie。

现在,当我使用此方法在数据库中删除用户时

deleteuser.php

$stmt = $pdo->prepare("DELETE FROM users WHERE id=:uid");
$stmt->bindValue(':uid', $uid);
$stmt->execute();
if($stmt){ 
$stmt2 = $pdo->prepare("DELETE FROM auth_tokens WHERE userid=:uid");
$stmt2->bindValue(':uid', $uid);
$stmt2->execute();
}

当同一用户重新访问页面(index.php)时,我在页面顶部收到此错误

警告:hash_equals():期望known_string为字符串,在第17行的C:\ xampp \ htdocs \ book \ php \ function.php中给出空值

index.php

include('php/function.php');
getcookie();

function.php

if (!empty($_COOKIE['remember'])) {
list($selector, $authenticator) = explode(':', $_COOKIE['remember']);
$stmt = $pdo->prepare("SELECT * FROM auth_tokens WHERE selector=:selector");
$stmt->bindValue(':selector', $selector);
$stmt->execute();
$row = $stmt->fetch();

if (hash_equals($row['token'], hash('sha256',
base64_decode($authenticator)))) {
.....
}
}

function getcookie (){

if (!empty($_COOKIE['remember'])) {
    list($selector, $authenticator) = explode(':', $_COOKIE['remember']);
    $stmt = $pdo->prepare("SELECT * FROM auth_tokens WHERE 
 selector=:selector");
    $stmt->bindValue(':selector', $selector);
    $stmt->execute();
    $row = $stmt->fetch();
    $toke = $row['token'];
    $auth = hash('sha256', base64_decode($authenticator));       
    if (hash_equals($row['token'], hash('sha256',
    base64_decode($authenticator)))) {
    $userid = $row['userid'];
    // Then regenerate login token as above
    }
 }
}

如何调整这些代码,以便可以通过结束用户会话和cookie来有效地从我的网站中删除用户。

1 个答案:

答案 0 :(得分:1)

您不能删除用户一方的会话/ Cookie ...但是您可以立即删除他们执行管理事务的能力。

如果在执行任何管理员级别的操作之前在服务器上基于用户的sessionID或其他方式重新检查了用户的凭据,则将有效禁用其管理员状态-然后将其转移到非管理员屏幕同时。

您可能会问:当我对他们进行核对时,如果他们具有管理员屏幕并处于活动状态怎么办?对于静态屏幕,您几乎无能为力(他们可以截取屏幕截图-您无法阻止它)。他们可以点击后退按钮,甚至可以从缓存中查看屏幕。但是

一些可能的解决方案是:

(a)每隔X秒/分钟将ajax与setInterval(或递归setTimeout)函数一起使用,以与服务器重新检查其管理凭据。然后,即使它们是afk,也可以从管理屏幕中注销。 (当然,精明的用户可以通过在DevTools中浏览来暂停此方法。)

(b)在执行任何管理员操作之前,都要重新检查其信誉。如果他们不再是管理员,则该操作将被拒绝,并返回到非管理员屏幕。精明的用户不会干扰此方法。

这不会给所有内容带来明显的延迟吗?

不。重新检查凭据就像在数据库中实时检查其用户权限状态一样简单。

当您取消管理它们时,您将更改它们的priv级别,因此,只要用户尝试从该管理屏幕执行某项操作,此权限级别就会立即被获取。除非您有数千名用户,否则不要担心这样做的开销。即使有数千名用户,它仍然可能是处理此问题的一种不错的方式。无论如何,您此时都在与服务器进行通信,并且在每个admin-action功能内,只需插入一个快速检查以“验证管理员状态”-因此,它只是服务器上与其自身数据库进行通信的后端代码。超级快。