我正在开发一个登录/注册系统。 遵循此PHP login system: Remember Me (persistent cookie)
之后我能够成功设置Cookie,但是在验证当前用户时遇到问题。
Register.php
if($login)
{
$_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,
'/',
false
);
header("location: ../home.php");
exit();
}
Check.php
这是问题所在。 如何检查Cookie并执行操作
$selector = base64_encode(random_bytes(9));
$authenticator = random_bytes(33);
$token = hash('sha256', $authenticator);
$expires = date('Y-m-d\TH:i:s', time() + 864000);
if(empty($_SESSION['userid']) && !empty($_COOKIE['remember']))
{
$sql = $pdo->prepare("SELECT * FROM auth_tokens WHERE selector = ?");
$sql->bindValue(1, $selector);
$sql->execute();
$row = $sql->fetch();
if (hash_equals($row['token'], hash('sha256',
base64_decode($authenticator)))) {
$_SESSION['userid'] = $row['userid'];
// Then regenerate login token as above
$selector = base64_encode(random_bytes(9));
$authenticator = random_bytes(33);
$token = hash('sha256', $authenticator);
$expires = date('Y-m-d\TH:i:s', time() + 864000);
$st = $pdo->prepare("UPDATE auth_tokens SET (selector,token,userid,expires)
VALUES (:selector, :token, :userid, :expires)");
$st->bindParam(':selector', $selector);
$st->bindParam(':token', $token);
$st->bindParam(':userid', $userid);
$st->bindParam(':expires', $expires);
$st->execute();
setcookie(
'remember',
$selector.':'.base64_encode($authenticator),
time()+86400,
'/',
false
);
header('Location: home.php');
exit;
}
我知道了-警告-“ hash_equals()期望known_string为字符串,给定NULL”。
我想要的
如果会话不存在(用户关闭浏览器), 并访问check.php页面, 如果存在cookie,我希望用户转到home.php页面。
PS
UPDATE查询不会为当前用户更新auth_token表。
该链接未说明有关存储用户ID会话的任何内容,但我认为这是必需的。 但是,当用户关闭浏览器时,会话用户ID被破坏,因此我不确定这行代码如何工作 $ _ SESSION ['userid'] = $ row ['userid']; 因此,可能会返回NULL作为警告。
是否有人使用此持久登录方法具有代码或方法来检查页面加载时的身份验证?
答案 0 :(得分:0)
首先,hash_equals(http://php.net/manual/en/function.hash-equals.php)期望其第一个参数($ known_string)为“某物”,而不是null。
在这里,您使用$row['token']
进行调用。如果为null,则hash_equals返回您得到的错误。
所以:
$row['token']
中是否有值。使用if (!empty($row['token']) ...
。然后,当查询没有返回令牌时,您必须编写一些逻辑以执行某些操作。据我对您的问题的了解,如果找不到令牌,您希望用户返回home.php吗?因此,请使用以下内容:
if (!$empty($row['token']))
{
# here put your code if the user HAS an associated token
{
else
{
# here put the redirection
header('Location: http://YOURDOMAIN/home.php');
}
请注意,为了使位置标头正常工作,NOTHING可以在之前发送给客户端。没有回声,没有html,什么都没有!
第二),如您在评论中所述,选择器是在用户首次连接时随机创建的。然后将该数字存储在创建的Cookie中。
您的check.php页面应该读取cookie的值,而不是生成新的随机数。否则,您的查询将始终不返回任何内容。 Cookie值存储在$ _COOKIE中。
并祝贺您使用准备好的语句!