453*_*066 5 php security session
我正在尝试实现一个 PHP 持久登录解决方案来保护我正在处理的网站上的一些管理页面,使用这个 SO 答案作为基础:
登录后
if ($login->success && $login->rememberMe) { // However you implement it
$selector = base64_encode(openssl_random_pseudo_bytes(9));
$authenticator = openssl_random_pseudo_bytes(33);
setcookie(
'remember',
$selector.':'.base64_encode($authenticator),
time() + 864000,
'/',
'yourdomain.com',
true, // TLS-only
true // http-only
);
$database->exec(
"INSERT INTO auth_tokens (selector, token, userid, expires) VALUES (?, ?, ?, ?)",
[
$selector,
hash('sha256', $authenticator),
$login->userId,
date('Y-m-d\TH:i:s', time() + 864000)
]
);
}
Run Code Online (Sandbox Code Playgroud)
在页面加载时重新验证
if (empty($_SESSION['userid']) && !empty($_COOKIE['remember'])) {
list($selector, $authenticator) = explode(':', $_COOKIE['remember']);
$row = $database->selectRow(
"SELECT * FROM auth_tokens WHERE selector = ?",
[
$selector
]
);
if (hash_equals($row['token'], hash('sha256', base64_decode($authenticator)))) {
$_SESSION['userid'] = $row['userid'];
// Then regenerate login token as above
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我不明白“重新验证页面加载”部分中的这一部分是什么意思:
// Then regenerate login token as above
Run Code Online (Sandbox Code Playgroud)
这是它所指的登录令牌 - 这是否意味着这一点:
$selector = base64_encode(openssl_random_pseudo_bytes(9));
Run Code Online (Sandbox Code Playgroud)
或者这一点:
$authenticator = openssl_random_pseudo_bytes(33);
Run Code Online (Sandbox Code Playgroud)
一旦我这样做了,我是否必须:
整个星期我一直在尝试各种持久登录的选项,这几乎让我到达那里,但我在最后一个块上磕磕绊绊。
当您第一次登录时,如果您选中“记住我”框,将会发生两件事:
selector:verifier该标记由连接的字符串组成。
当您的用户下次访问您的网站时,如果他们没有活动会话,Cookie 将用于自动将他们作为关联用户登录。然后,应在双方(浏览器和数据库)上丢弃该令牌,并应生成一个新令牌来取代它。
最终结果是:对于最终用户来说,就像他们永远登录一样(直到他们明确注销,这将使令牌无效)。