如何在 PHP 中使用登录 cookie 连接用户?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18740543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to connect user with a login cookie in PHP?
提问by LPB
First of all, I am testing on localhost. I have this index.php file which contains the following "remember me" checkbox:
首先,我正在本地主机上进行测试。我有这个 index.php 文件,其中包含以下“记住我”复选框:
<input type="checkbox" id="login_remember" name="login_remember">
The login form posts to loginvalidate.php, which includes the following php script. I have included a lot of comments to ease the process of reading my code. Note that I'm pretty sure that everything below works fine.
登录表单发布到 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();
}
Then, when I close the internet browser and come back to index.php, I want the cookie to automatically connect the user. This is in my index.php:
然后,当我关闭 Internet 浏览器并返回 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";
}
}
The problem is, it never echoes "lol". Also, does anyone have any insight on how I could connect the users? AKA, what should go inside these lines:
问题是,它从不回响“lol”。另外,有没有人对我如何连接用户有任何见解?AKA,这些行内应该包含什么:
if ($key == $cookie_key){
echo "lol";
}
Thank you! I'm still new to PHP and SQL so please bear with me if I have made some beginner errors.
谢谢!我还是 PHP 和 SQL 的新手,所以如果我犯了一些初学者错误,请多多包涵。
EDIT!: After looking again and again at my code, I think that my error might lie in these lines. I'm not sure about the syntax, and the method I am using to store values into $token and $randomNumber:
编辑!:反复查看我的代码后,我认为我的错误可能出在这些行中。我不确定语法,以及我用来将值存储到 $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'];
回答by mathielo
There are basically two ways you can implement a login script in PHP:
基本上有两种方法可以在 PHP 中实现登录脚本:
I'll try to explain both uses in a rawform below, so keep in mind there is a lot more to know about each of them.
我将尝试在下面以原始形式解释这两种用法,因此请记住,关于它们中的每一种,还有很多东西需要了解。
Using Sessions
使用会话
Making it simple, sessions are unique and lives as long as the page is open (or until it timeouts). If your browser is closed, the same happens to the session.
简单来说,会话是唯一的,并且只要页面打开(或直到它超时)就存在。如果您的浏览器已关闭,会话也会发生同样的情况。
How to use it?
如何使用它?
They are pretty simple to implement. First, make sure you start sessions at the beginning of each page:
它们实施起来非常简单。首先,确保在每个页面的开头开始会话:
<?php session_start(); ?>
Note: It's important that this call comes before of any page output, or it will result in an "headers already sent" error.
注意:这个调用出现在任何页面输出之前很重要,否则会导致“headers already sent”错误。
Alright, now your session is up and running. What to do next? It's quite simple: user sends it's login/password through login form, and you validate it. If the login is valid, store it to the session:
好的,现在您的会话已启动并正在运行。接下来做什么?这很简单:用户通过登录表单发送其登录名/密码,然后您对其进行验证。如果登录有效,则将其存储到会话中:
if($validLoginCredentials){
$_SESSION['user_id'] = $id;
$_SESSION['user_login'] = $login;
$_SESSION['user_name'] = $name;
}
or as an array (which I prefer):
或作为数组(我更喜欢):
if($validLoginCredentials){
$_SESSION['user'] = array(
'name' => $name,
'login' => 'login',
'whichever_more' => $informationYouNeedToStore
);
}
Ok, now your user is logged in. So how can you know/check that? Just check if the session of an user exists.
好的,现在您的用户已登录。那么您怎么知道/检查呢?只需检查用户的会话是否存在。
if(isset($_SESSION['user_id'])){ // OR isset($_SESSION['user']), if array
// Logged In
}else{
// Not logged in :(
}
Of course you could go further, and besides of checking if the session exists, search for the session-stored user ID in the database to validate the user. It all depends on the how much security you need.
当然,您可以更进一步,除了检查会话是否存在之外,还可以在数据库中搜索会话存储的用户 ID 以验证用户。这完全取决于您需要多少安全性。
In the simplest application, there will never exist a $_SESSION['user'] unless you set it manually in the login action. So, simply checking for it's existence tells you whether the user is logged in or not.
在最简单的应用程序中,永远不会存在 $_SESSION['user'] 除非您在登录操作中手动设置它。因此,只需检查它的存在就可以告诉您用户是否已登录。
Loggin out: just destroy it. You could use
注销:只需销毁它。你可以用
session_destroy();
But keep in mind that this will destroy all sessionsyou have set up for that user. If you also used $_SESSION['foo'] and $_SESSION['bar'], those will be gone as well. In this case, just unset the specific session:
但请记住,这会破坏您为该用户设置的所有会话。如果您还使用了 $_SESSION['foo'] 和 $_SESSION['bar'],它们也会消失。在这种情况下,只需取消设置特定会话:
unset($_SESSION['user']);
And done! User is not logged in anymore! :)
并做了!用户不再登录!:)
Using Cookies
使用 Cookie
Cookies works somewhat alike sessions, except they are storedin the client browser and lasts as long as you tell them to. For instance, you were using cookies "as sessions" when you were setting them to expire at $timeNow.
Cookie 的工作方式与会话有些相似,不同之处在于它们存储在客户端浏览器中,并且只要您告诉它们就可以持续。例如,当您将 cookie 设置为在$timeNow到期时,您将其“作为会话”使用。
I usually don't like using cookies for simple logins as they require more advanced security checks. Since they are stored at users' browser, they can easily be manipulated and malicious users could generatefalse login information and log into your system.
我通常不喜欢使用 cookie 进行简单的登录,因为它们需要更高级的安全检查。由于它们存储在用户的浏览器中,因此很容易被操纵,恶意用户可能会生成虚假的登录信息并登录到您的系统。
How to use it?
如何使用它?
Pretty much as you do with sessions. The difference is about setting/unsetting the 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
To check if a user is logged in, you can use the same example as of the session, but using a different variable: $_COOKIE
要检查用户是否已登录,您可以使用与会话相同的示例,但使用不同的变量:$_COOKIE
if(isset($_COOKIE['user']['id'] && !empty(isset($_COOKIE['user']['id']))){
// Logged In
}else{
// Not logged in :(
}
Well, that's it. To remind you again, these are very simplelogin methods examples. You'll need to study a bit more about both methods and improve your code with some more layers of security checks depending on the security requirements of your application.
嗯,就是这样。再次提醒您,这些是非常简单的登录方法示例。您需要更多地研究这两种方法,并根据应用程序的安全要求,通过更多的安全检查层来改进您的代码。
回答by Shushant
reason behind your code is not working is
您的代码无法正常工作背后的原因是
setcookie("rememberme", $email . "," . $key, $timenow); // this is getting expire exactly at same time when it is set
replace it with
将其替换为
setcookie("rememberme", $email . "," . $key, time() * 3600);//expire after 1hour