记住登录系统,怎么做?

时间:2016-06-10 10:03:22

标签: php cookies

我已经搜索过并发现了一千个关于我的问题的问题,我试图解决但没有得到帮助。所以我为我的具体案例打开了这个帖子,我希望你能帮助我。

我说到了,我正在PDO中创建一个登录系统,是初学者,但我希望它能在一段时间内通过cookie登录。

我做了几次测试,但没有结果。浏览器已关闭,必须重新输入凭据。

我再说一遍,我已经在网站上搜索过,但还没有设法解决。

的login.php

if (empty($_POST) === false) {
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);

    if (empty($username) === true || empty($password) === true) {
        $errors[] = 'Sorry, but we need your username and password.';

    } else if ($users->user_exists($username) === false) {
        $errors[] = 'Sorry that username doesn\'t exists.';

    } else if ($users->email_confirmed($username) === false) {
        $errors[] = 'Sorry, but you need to activate your account. Please check your email.';

    } else {

        $login = $users->login($username, $password);

        if ($login === false) {
            $errors[] = 'Sorry, that username/password is invalid';    
        } else {
            $_SESSION['id'] =  $login; // The user's id is now set into the user's session  in the form of $_SESSION['id']
            $_SESSION['username'] = $usr;

                $cookie_name = '_name_cookie_';         
                $hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 12]); // will result in a 32 characters hash
                $cookie_time = (3600 * 24 * 30); // 30 days
                setcookie($cookie_name, 'usr='.$usr.'&hash='.$hash, time() + $cookie_time);    


            header('Location: home.php');
            exit();
        }
    }
}

课程: users.php

public function login($username, $password) {
    $this->db->query("SELECT * FROM users WHERE username = :username");
    $this->db->bind(':username', $username);
    $data = $this->db->single();

    $hash = $data['password'];
    $id = $data['id'];

    #hashing the supplied password and comparing it with the stored hashed password.
    if (password_verify($password, $hash)) {
        return $id; 
    }else{
        return false; 
    }
}

注意:目前在形式上我不想整合检查"记住我",我稍后会这样做。

但是,我不能如何保持登录用户,cookie被正确插入,否则它不起作用。我该如何解决?

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点,有些方法比其他方法更好。有关于它的一些信息,甚至在这个网站上,但我会支出这个概念。

首先,您需要某种令牌或其他东西来识别客户端的用户。这通常使用$_COOKIE来完成。我喜欢设置两个单独的cookie,一个具有用户ID,另一个具有散列令牌,因此即使有人猜到令牌(这是极不可能的),他们也需要匹配的用户ID。使用代码中的示例,这将是生成所述cookie的示例代码

// Define variables
define("COOKIE_DURATION", time()+60*60*24*30); // 30 days
$userHash = hash("sha256", $_SESSION['id'].time());

// Set the cookies
setcookie("RememberMeID", $_SESSION['id'], COOKIE_DURATION);
setcookie("RememberMeHash", $userHash, COOKIE_DURATION);

这使用当前时间和用户名组合,然后散列,以便我们可以将其用作标识符。我已经使用了sha256,因为它不是我们存储的密码,应该没问题。

接下来,我们需要识别具有这两个cookie的用户。因此,这些数据也必须存储在服务器中,因此我们可以在用户访问网站时匹配它们。您可以使用数据库,例如包含此信息的单独rememberMe表。这可能包含您之前使用用户ID创建的哈希。因此,您需要将其插入数据库中。

$stmt = $pdo->prepare("INSERT INTO rememberMe (userID, userHash) VALUES (:id, :hash)");
$stmt->execute(array("id" => $_SESSION['id'], "hash" => $userHash));

然后,您可以简单地检查两个cookie是否都已设置,而会话未设置,查看数据是否匹配 - 如果匹配,则设置其会话!

// If we're not logged in, and the two cookies are set, we can check if something matches
if (!isset($_SESSION['id']) && !empty($_COOKIE['RememberMeID']) && !empty($_COOKIE['RememberMeHash'])) {
    // Check if the cookies match something in the DB...
    $stmt = $pdo->prepare("SELECT COUNT(*) as `count`, userID FROM rememberMe WHERE userID=:id AND userHash=:hash");
    $stmt->execute(array("id" => $_COOKIE['RememberMeID'], "hash" => $_COOKIE['RememberMeHash']));
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    // If it does, we log them in and renew the cookie
    if ($row['count'] > 0) {
        $_SESSION['id'] = $row['userID'];
        setcookie("RememberMeID", $_SESSION['id'], COOKIE_DURATION);
        setcookie("RememberMeHash", $_COOKIE['RememberMeHash'], COOKIE_DURATION);
    }
}

您还可以阅读以下主题:What is the best way to implement "remember me" for a website?

答案 1 :(得分:0)

非常感谢你的帮助。我当时正在这样做:

    if (empty($_POST) === false) {
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);

    if (empty($username) === true || empty($password) === true) {
        $errors[] = 'Sorry, but we need your username and password.';

    } else if ($users->user_exists($username) === false) {
        $errors[] = 'Sorry that username doesn\'t exists.';

    } else if ($users->email_confirmed($username) === false) {
        $errors[] = 'Sorry, but you need to activate your account. Please check your email.';

    } else {

        $login = $users->login($username, $password);

        if ($login === false) {
            $errors[] = 'Sorry, that username/password is invalid';    
        } else {

            if (!isset($_SESSION['id']) && !empty($_COOKIE['RememberMeID']) && !empty($_COOKIE['RememberMeHash'])) {
                $db->query("SELECT * FROM rememberMe WHERE userID = :userID AND userHash = :userHash");
                $db->bind(':userID', $_COOKIE['RememberMeID']);
                $db->bind(':userHash', $_COOKIE['RememberMeHash']);
                $db->resultset();
                $row = $db->rowCount();

                if ($row['count'] > 0) {
                    $_SESSION['id'] = $login;
                    setcookie("RememberMeID", $_SESSION['id'], COOKIE_DURATION);
                    setcookie("RememberMeHash", $_COOKIE['RememberMeHash'], COOKIE_DURATION);
                    header('Location: home.php');
                    exit();     
                }
            }
        }
    }
}

虽然,我想知道在哪里输入第一个代码以及在什么时间。实际上,必须在注册页面中插入插入令牌的代码,以便将注册用户输入数据库?