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

时间:2013-09-11 11:57:26

标签: php sql cookies encryption login

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

<input type="checkbox" id="login_remember" name="login_remember">

登录表单发布到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();
    }

然后,当我关闭互联网浏览器并返回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";
        }
    }

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

if ($key == $cookie_key){
            echo "lol";
        }

谢谢!我还是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'];

3 个答案:

答案 0 :(得分:21)

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

  1. 使用Sessions
  2. 使用Cookies
  3. 我将尝试在下面的原始表单中解释这两种用法,因此请记住,还有很多要了解它们。

    使用会话

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

    如何使用它?

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

    <?php session_start(); ?>
    

    注意:此调用在任何页面输出之前进行,这一点很重要,否则会导致“已发送标题”错误。

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

    if($validLoginCredentials){
        $_SESSION['user_id'] = $id;
        $_SESSION['user_login'] = $login;
        $_SESSION['user_name'] = $name;
    }
    

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

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

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

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

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

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

    登出:只需销毁它。你可以用

    session_destroy();
    

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

    unset($_SESSION['user']);
    

    完成了!用户不再登录! :)

    使用Cookie

    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
    

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

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

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

答案 1 :(得分:3)

你的代码背后的原因是

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

替换为

 setcookie("rememberme", $email . "," . $key, time() * 3600);//expire after 1hour 

答案 2 :(得分:0)

time()*60*60*24*365*30

这个时间大于 9999 年,你也不需要设置这个恐怖饼干时间。 您设置的 cookie 时间大于 9999 年,php 不允许此配置。 在我看来,最好的解决方案是设置新的过期 cookie 时间低于 9999 :))