如何在PHP中将用户与登录cookie连接?

LPB*_*LPB 5 php sql encryption cookies login

首先,我在localhost上测试.我有这个index.php文件,其中包含以下"记住我"复选框:

<input type="checkbox" id="login_remember" name="login_remember">
Run Code Online (Sandbox Code Playgroud)

登录表单发布到loginvalidate.php,其中包含以下php脚本.我已经包含了很多注释来简化阅读代码的过程.请注意,我很确定以下所有内容都可以正常工作.

if (isset($_POST['login_submit'])) {  //SETS VARIABLES FROM FORM
$email = $_POST[trim('login_email')];
$password = $_POST['login_password'];
$remember = isset($_POST['login_remember']) ? '1' : '0';

$db_found = mysqli_select_db($db_handle,$sql_database);  //OPENING TABLE

$query = "SELECT password FROM registeredusers WHERE email = '$email'";
$result = mysqli_query($db_handle, $query) or die (mysqli_error($db_handle));

$row = mysqli_fetch_assoc($result);
$numrows = mysqli_num_rows($result);
if ($numrows!=0)  //IF EMAIL IS REGISTERED
{
  if ($row['password'] == $password) {  //IF PASSWORD IN DATABASE == PASSWORD INPUT FROM FORM
        if ($remember == '1'){  //IF USER WANTS TO BE REMEMBERED
        $randomNumber = rand(99,999999);  //RANDOM NUMBER TO SERVE AS A KEY
        $token = dechex(($randomNumber*$randomNumber));  //CONVERT NUMBER TO HEXADECIMAL FORM
        $key = sha1($token . $randomNumber);
        $timeNow = time()*60*60*24*365*30;  //STOCKS 30 YEARS IN THE VAR

         $sql_database = "registeredusers";
         $sql_table = "rememberme";

         $db_found = mysqli_select_db($db_handle,$sql_database);  //OPENING TABLE

         $query_remember = "SELECT email FROM rememberme WHERE email = '$email'";  //IS THE USER IN TABLE ALREADY
         $result = mysqli_query($db_handle, $query_remember) or die (mysqli_error($db_handle));

        if (mysqli_num_rows($result) > 0) {  //IF USER IS ALREADY IN THE REMEMBERME TABLE
         $query_update = "UPDATE rememberme SET
         email      = '$email'
         user_token = '$token'
         token_salt = '$randomNumber'
         time       = '$timeNow'";
    }
    else {  //OTHERWISE, INSERT USER IN REMEMBERME TABLE
         $query_insert = "INSERT INTO rememberme
        VALUES( '$email', '$token', '$randomNumber', '$timeNow' )";
    }
  setcookie("rememberme", $email . "," . $key, $timenow);
    }
          header('Location: homepage.php');  //REDIRECTS: SUCCESSFUL LOGIN
        exit();
    }
Run Code Online (Sandbox Code Playgroud)

然后,当我关闭互联网浏览器并返回index.php时,我希望cookie自动连接用户.这是在我的index.php中:

include 'db_connect.php';
    $sql_database = "registeredusers";
    $db_found = mysqli_select_db($db_handle,$sql_database);  //OPENING TABLE
    session_start();
    if (isset($_COOKIE['rememberme'])) {
        $rememberme = explode(",", $_COOKIE["rememberme"]);
        $cookie_email = $rememberme[0];
        $cookie_key = $rememberme[1];

        $query_remember = "SELECT * FROM rememberme WHERE email = '$cookie_email'";  //IS THE USER IN TABLE ALREADY
        $result_remember = mysqli_query($db_handle, $query_remember) or die (mysqli_error($db_handle));

        $row = mysqli_fetch_assoc($result_remember);
            $token = $row['user_token'];
            $randomNumber = $row['token_salt'];
        $key = sha1($token . $randomNumber);  //ENCRYPT TOKEN USING SHA1 AND THE RANDOMNUMBER AS SALT

        if ($key == $cookie_key){
            echo "lol";
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题是,它从不回应"大声笑".此外,有没有人有任何关于如何连接用户的见解?AKA,这些内容应该是什么:

if ($key == $cookie_key){
            echo "lol";
        }
Run Code Online (Sandbox Code Playgroud)

谢谢!我还是PHP和SQL的新手,所以如果我犯了一些初学者错误,请耐心等待.

编辑!:在我的代码中反复查看之后,我认为我的错误可能在于这些行.我不确定语法,以及我用来将值存储到$ token和$ randomNumber中的方法:

$query_remember = "SELECT * FROM rememberme WHERE email = '$cookie_email'";  //IS THE USER IN TABLE ALREADY
    $result_remember = mysqli_query($db_handle, $query_remember) or die (mysqli_error($db_handle));

    $row = mysqli_fetch_assoc($result_remember);
        $token = $row['user_token'];
        $randomNumber = $row['token_salt'];
Run Code Online (Sandbox Code Playgroud)

mat*_*elo 24

基本上有两种方法可以在PHP中实现登录脚本:

  1. 使用会话
  2. 使用Cookies

我将尝试在下面的原始表单中解释这两种用法,因此请记住,有关它们的更多信息.

使用会话

简单来说,会话​​是独一无二的,只要页面打开(或直到超时),它们就会存在.如果您的浏览器已关闭,则会话也会发生同样的情况.

如何使用它?

它们很容易实现.首先,确保在每个页面的开头开始会话:

<?php session_start(); ?>
Run Code Online (Sandbox Code Playgroud)

注意:在任何页面输出之前进行此调用非常重要,否则将导致"已发送标头"错误.

好的,现在您的会话已启动并正在运行.接下来做什么?这很简单:用户通过登录表单发送登录名/密码,然后验证它.如果登录有效,请将其存储到会话中:

if($validLoginCredentials){
    $_SESSION['user_id'] = $id;
    $_SESSION['user_login'] = $login;
    $_SESSION['user_name'] = $name;
}
Run Code Online (Sandbox Code Playgroud)

或者作为一个数组(我更喜欢):

if($validLoginCredentials){
    $_SESSION['user'] = array(
        'name' => $name,
        'login' => 'login',
        'whichever_more' => $informationYouNeedToStore
    );
}
Run Code Online (Sandbox Code Playgroud)

好的,现在您的用户已登录.那么您如何知道/检查?只需检查用户的会话是否存在.

if(isset($_SESSION['user_id'])){ // OR isset($_SESSION['user']), if array
// Logged In
}else{
// Not logged in :(
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以更进一步,除了检查会话是否存在之外,还要在数据库中搜索会话存储的用户ID以验证用户.这完全取决于您需要多少安全性.

在最简单的应用程序中,除非您在登录操作中手动设置,否则永远不会存在$ _SESSION ['user'].因此,只需检查它的存在就会告诉您用户是否已登录.

登出:只是销毁它.你可以用

session_destroy();
Run Code Online (Sandbox Code Playgroud)

但请记住,这将破坏您为该用户设置的所有会话.如果你还使用了$ _SESSION ['foo']和$ _SESSION ['bar'],那些也会消失.在这种情况下,只需取消设置特定会话:

unset($_SESSION['user']);
Run Code Online (Sandbox Code Playgroud)

并做了!用户不再登录!:)

使用Cookies

Cookie会在某种程度上类似于会话,除非它们存储在客户端浏览器中,并且只要您告诉它们就会持续.例如,当您将cookie设置为以$ timeNow到期时,您使用cookie"作为会话" .

我通常不喜欢使用cookie进行简单登录,因为它们需要更高级的安全检查.由于它们存储在用户的浏览器中,因此很容易被操纵,恶意用户可能会生成错误的登录信息并登录到您的系统.

如何使用它?

就像你在会话中一样.不同之处在于设置/取消设置cookie:

// To set a Cookie
// You could use the array to store several user info in one cookie
$user = array(
    'id' => $id,
    'name' => $name,
    'login' => $login,
)
setcookie("loginCredentials", $user, time() * 7200); // Expiring after 2 hours

// Now to log off, just set the cookie to blank and as already expired
setcookie("loginCredentials", "", time() - 3600); // "Expires" 1 hour ago
Run Code Online (Sandbox Code Playgroud)

要检查用户是否已登录,您可以使用与会话相同的示例,但使用其他变量:$ _COOKIE

if(isset($_COOKIE['user']['id'] && !empty(isset($_COOKIE['user']['id']))){
// Logged In
}else{
// Not logged in :(
}
Run Code Online (Sandbox Code Playgroud)

嗯,就是这样.再次提醒您,这些是非常简单的登录方法示例.您需要更多地研究这两种方法,并根据应用程序的安全要求,通过更多层次的安全检查来改进代码.


小智 6

您的代码无法正常工作背后的原因是

  setcookie("rememberme", $email . "," . $key, $timenow); // this is getting expire exactly at same time when it is set
Run Code Online (Sandbox Code Playgroud)

将其替换为

 setcookie("rememberme", $email . "," . $key, time() * 3600);//expire after 1hour 
Run Code Online (Sandbox Code Playgroud)

  • 应为“time() + 3600”(加,而不是乘),一小时后过期。 (2认同)