Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 设置cookie后重新验证页面加载_Php_Session_Cookies - Fatal编程技术网

Php 设置cookie后重新验证页面加载

Php 设置cookie后重新验证页面加载,php,session,cookies,Php,Session,Cookies,我正在开发一个登录/注册系统。 此后 我能够成功设置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:

我正在开发一个登录/注册系统。 此后

我能够成功设置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

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();
}
这就是问题所在。 如何检查饼干并做一些事情

$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()期望已知的字符串为字符串,给定NULL”。

我想要什么

如果会话不存在(用户关闭浏览器), 并访问check.php页面, 如果存在cookie,我希望用户转到home.php页面

p.S

更新查询未更新当前用户的身份验证令牌表

这个链接没有说任何关于存储用户ID会话的内容,但我觉得它是必要的。 但是当用户关闭浏览器时,会话用户id将被销毁,因此我不确定这行代码如何工作 因此,可能会返回NULL作为给出的警告

任何人如果有代码或方法可以使用这种持久登录方法检查页面加载时的身份验证?

首先)hash_equals()希望其第一个参数($known_string)是“something”,而不是null

这里您使用
$row['token']
调用它。如果为null,hash_equals将返回您得到的错误

因此:

  • 您的查询没有返回任何结果
  • 在调用hash_equals之前,应该检查
    $row['token']
    中是否有值。如果(!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');
    }
    
要小心,为了让位置头工作,以前不能向客户端发送任何内容。没有回音,没有html,什么都不能


第二)如您在评论中所述,选择器是在用户首次连接时随机创建的。然后将该数字存储在创建的cookie中

php页面应该读取cookie的值,而不是生成新的随机数。否则,您的查询将始终不返回任何内容。cookie值存储在$\u cookie中


祝贺你使用事先准备好的声明

我认为问题在于这个查询$sql=$pdo->prepare(“SELECT*from auth_tokens,其中selector=?”;每次重新加载页面时选择器都会更改,导致其随机性,因此选择器base64_编码(随机_字节(9));与选择器列中的任何内容都不匹配。确实如此。在check.php页面中,应使用与创建帐户时相同的选择器。该选择器可以存储为cookie值,而不是随机值。