我想创建一个用户登录的简单登录系统,然后它将保存用户登录的详细信息,并且他们将始终登录,直到他们点击注销链接。现在我听说用户使用cookie会更好。以下是登录页面:
teacherlogin.php脚本:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php
// connect to the database
include('connect.php');
include('member.php');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}
// required variables (make them explciit no need for foreach loop)
$teacherusername = (isset($_POST['teacherusername'])) ? $_POST['teacherusername'] : '';
$teacherpassword = (isset($_POST['teacherpassword'])) ? $_POST['teacherpassword'] : '';
$loggedIn = false;
$active = true;
if ((isset($username)) && (isset($userid))){
echo "You are already Logged In: <b>{$_SESSION['teacherforename']} {$_SESSION['teachersurname']}</b> | <a href='./menu.php'>Go to Menu</a> | <a href='./teacherlogout.php'>Logout</a>";
}
else{
if (isset($_POST['submit'])) {
$teacherpassword = md5(md5("g3f".$teacherpassword."rt4"));
// don't use $mysqli->prepare here
$query = "SELECT TeacherId, TeacherForename, TeacherSurname, TeacherUsername, TeacherPassword, Active FROM Teacher WHERE TeacherUsername = ? AND TeacherPassword = ? LIMIT 1";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("ss",$teacherusername,$teacherpassword);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbTeacherId, $dbTeacherForename,$dbTeacherSurname,$dbTeacherUsername,$dbTeacherPassword, $dbActive);
while($stmt->fetch()) {
if ($teacherusername == $dbTeacherUsername && $teacherpassword == $dbTeacherPassword) {
if ($dbActive == 0) {
$loggedIn = false;
$active = false;
echo "You Must Activate Your Account from Email to Login";
}else {
$loggedIn = true;
$active = true;
$_SESSION['teacherid'] = $dbTeacherId;
$_SESSION['teacherusername'] = $dbTeacherUsername;
}
}
}
if ($loggedIn == true){
$_SESSION['teacherforename'] = $dbTeacherForename;
$_SESSION['teachersurname'] = $dbTeacherSurname;
header( 'Location: menu.php' ) ;
die();
}
if (!$loggedIn && $active && isset($_POST)) {
echo "<span style='color: red'>The Username or Password that you Entered is not Valid. Try Entering it Again</span>";
}
/* close statement */
$stmt->close();
/* close connection */
$mysqli->close();
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Teacher Login</title>
<link rel="stylesheet" type="text/css" href="TeacherLoginStyle.css">
</head>
<body>
<?php
include('noscript.php');
?>
<h1>TEACHER LOGIN</h1>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post" id="teachLoginForm">
<p>Username</p><p><input type="text" name="teacherusername" /></p> <!-- Enter Teacher Username-->
<p>Password</p><p><input type="password" name="teacherpassword" /></p> <!-- Enter Teacher Password-->
<p><input id="loginSubmit" type="submit" value="Login" name="submit" /></p>
</form>
<a href="./forgotpass.php">Forgot Password</a>
</body>
<?php
}
?>
在上面的代码中,用户将在相关的文本输入中输入他们的用户名和密码。当他们提交登录详细信息时,它将检查数据库以查看他们的登录详细信息是否与数据库匹配。
现在我要做的是将用户的用户名和id的详细信息存储在php脚本(member.php)中,以便它知道哪个用户已登录。但是目前我正在使用$ SESSION执行此操作包含很短的时间:
member.php页面:
<?php
if (isset($_SESSION['teacherid'])) {
$userid = $_SESSION['teacherid'];
}
if (isset($_SESSION['teacherusername'])) {
$username = $_SESSION['teacherusername'];
}
?>
如何更改上面的代码以获取Cookie,以便会员页面中的用户详细信息将保持无限时间(直到他们退出当然)。
更新:
好的,这是数据库中的Teacher
表:
TeacherId (auto PK) TeacherForename TeacherSurname TeacherUsername, TeacherPassword
1 John Parks j.parks b018460fba79b
2 Mary Little u0876555 a33rfe3tn12e3
3 Jim Owen owensjimmy fkof04r3fk422
所以你是说首先在上面的表中添加一个SessionId列并存储在每个用户的复杂id中,例如34dekfm45345
。
然后我真的需要你的帮助,以便能够看到有关如何找到正确的SessionId和删除SessionId的代码。
更新2:
因此,如果我理解正确,下面是php脚本的样子:
teacherlogin.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php
// connect to the database
include('connect.php');
include('member.php');
include('sessionuser.php');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}
// required variables (make them explciit no need for foreach loop)
$teacherusername = (isset($_POST['teacherusername'])) ? $_POST['teacherusername'] : '';
$teacherpassword = (isset($_POST['teacherpassword'])) ? $_POST['teacherpassword'] : '';
$loggedIn = false;
$active = true;
if ((isset($username)) && (isset($userid))){
echo "You are already Logged In: <b>{$_SESSION['teacherforename']} {$_SESSION['teachersurname']}</b> | <a href='./menu.php'>Go to Menu</a> | <a href='./teacherlogout.php'>Logout</a>";
}
else{
if (isset($_POST['submit'])) {
$teacherpassword = md5(md5("g3f".$teacherpassword."rt4"));
// don't use $mysqli->prepare here
$query = "SELECT TeacherId, TeacherForename, TeacherSurname, TeacherUsername, TeacherPassword, Active FROM Teacher WHERE TeacherUsername = ? AND TeacherPassword = ? LIMIT 1";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("ss",$teacherusername,$teacherpassword);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbTeacherId, $dbTeacherForename,$dbTeacherSurname,$dbTeacherUsername,$dbTeacherPassword, $dbActive);
while($stmt->fetch()) {
if ($teacherusername == $dbTeacherUsername && $teacherpassword == $dbTeacherPassword) {
if ($dbActive == 0) {
$loggedIn = false;
$active = false;
echo "You Must Activate Your Account from Email to Login";
}else {
$loggedIn = true;
$active = true;
$_SESSION['teacherid'] = $dbTeacherId;
$_SESSION['teacherusername'] = $dbTeacherUsername;
}
}
}
if ($loggedIn == true){
$_SESSION['teacherforename'] = $dbTeacherForename;
$_SESSION['teachersurname'] = $dbTeacherSurname;
header( 'Location: menu.php' ) ;
die();
}
if (!$loggedIn && $active && isset($_POST)) {
echo "<span style='color: red'>The Username or Password that you Entered is not Valid. Try Entering it Again</span>";
}
/* close statement */
$stmt->close();
/* close connection */
$mysqli->close();
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Teacher Login</title>
<link rel="stylesheet" type="text/css" href="TeacherLoginStyle.css">
</head>
<body>
<?php
include('noscript.php');
?>
<h1>TEACHER LOGIN</h1>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post" id="teachLoginForm">
<p>Username</p><p><input type="text" name="teacherusername" /></p> <!-- Enter Teacher Username-->
<p>Password</p><p><input type="password" name="teacherpassword" /></p> <!-- Enter Teacher Password-->
<p><input id="loginSubmit" type="submit" value="Login" name="submit" /></p>
</form>
<a href="./forgotpass.php">Forgot Password</a>
</body>
<?php
}
?>
我没有更改检查用户当前是否登录的代码,是否将其从if ((isset($username)) && (isset($userid))){
更改为任何相关内容?我在上面添加了`include(sessionuser.php)代码
member.php脚本:
<?php
if (isset($_SESSION['teacherid'])) {
$userid = $_SESSION['teacherid'];
}
if (isset($_SESSION['teacherusername'])) {
$username = $_SESSION['teacherusername'];
}
?>
我还需要上面的member.php脚本吗?
sessionuser.php脚本:
$sessionUserID = false;
if (isset($_COOKIE['sessionUserID']) && preg_match('/^[a-z9-0]{32}$/i) {
$sessionUserID = $_COOKIE['sessionUserID'];
// Get the session details from the database
$sql = 'SELECT s.*, t.* FROM SessionUser s LEFT JOIN Teacher t ON s.TeacherId=t.TeacherId WHERE s.SessionUserId=:SessionUserId';
$aParams = array(':SessionUserId' => $sessionUserID)
$sessionRow = $stmnt->fetch();
if ($sessionRow) {
// User is logged in, and you have details in $sessionRow
// At this point, you can also validate other info such as the UserAgent, IP etc. All forgable, but can help add a littel security.
} else {
// Passed an invalid / expired session ID
$sessionUserID = false;
}
}
// If you don't have a session, create one
if (!$sessionUserID) {
// Create a session user ID - make it non sequential
// You should put this in a loop and check $sessionID is unique. Insert will fail is not unique
$sessionUserID = md5(time() . uniqid());
$sql = 'INSERT INTO SessionUser(SessionUserId, TeacherId)
VALUES(:SessionUserId, 0)';
$aParams = array(':SessionUserId' => $sessionUserID)
$smnt->execute();
// Default session details
$sessionRow = array('TeacherId'=>0);
// Now the cookie part
setcookie('sessionUserID', $sessionUserID, time() + howLongYouWant, '/');
}
// Not check for user logging in.
if (UserLogsIn) {
if ($sessionRow['teacher_id'] > 0) {
// Already logged in!?
} else {
$sql = 'UPDATE SessionUser SET Teacher_id=:TeacherId WHERE SessionUserId=:SessionUserId';
$aParams = array(':TeacherId'=>$TeacherId, ':SessionUserId' => $sessionUserID);
$smnt->execute();
// After a form post, always redirect to the same page or another page - stops the "do you want to resent this data" message on back button
// DO NOT echo anything before this point.
header('location: this page');
exit();
}
} elseif (UserLogsOut) {
if ($sessionRow['TeacherId'] == 0) {
// Not Logged In!?
} else {
$sql = 'UPDATE SessionUser SET TeacherId=0 WHERE SessionUserd=:SessionUserid';
$aParams = array(':session_id' => $sessionID);
$smnt->execute();
// After a form post, always redirect to the same page or another page - stops the "do you want to resent this data" message on back button
// DO NOT echo anything before this point.
header('location: this page');
exit();
}
}
sessionuser.php脚本代码是否包含上述所有代码是否正确?我已经更改了代码以尝试匹配下面的数据库表:
SessionUser表:
SessionUserId (CHAR32) PK
TeacherId (INT) //matches TeacherId field in teacher table
更新2是否正确?
答案 0 :(得分:3)
简单(但错误)的答案是,您将所有$_SESSION['blah'] = $value
替换为setcookie('blah', $value, time() + ages);
但问题是您在会话中存储用户信息 - 如果您存储在cookie中,该信息可以轻松更改。
因此,您需要一种本地(服务器上)存储个人详细信息的方式,以及一个用于调用这些详细信息的参考号 - 基本上您需要复制会话,但使用您自己的数据库(或文件存储)。
通常这是在数据库中完成的:您创建一个“会话”数据库,为每个用户提供一个唯一的sessionID(难以猜测,而不是直接数字),然后将该会话ID存储在cookie中,并存储个人详细信息在数据库中。然后你得到一个会话cookie,从数据库中回忆起他们的细节。当他们注销时,删除数据库中的条目等。如果服务器重新启动并且您丢失会话,则会话数据是安全的,因为它在数据库中 - 用户始终登录,直到您不想要它为止。
所以有一个简单的答案,以及真实的,更复杂的答案。
编辑:
根据要求,一个袖手旁观的过程。我错过了错误检查和所有爵士乐的DB调用。这应该让你开始。
// Create a DB with the following structure
session_id CHAR(32) PRIMARY KEY
teacher_id INT(mathc your teachers table)
// Check for cookie, validate it's an expected format
$sessionID = false;
if (isset($_COOKIE['sessionID']) && preg_match('/^[a-z9-0]{32}$/i) {
$sessionID = $_COOKIE['sessionID'];
// Get the session details from the database
$sql = 'SELECT s.*, t.* FROM sessions s LEFT JOIN teachers t ON s.teacher_id=t.teacher_id WHERE s.session_id=:session_id';
$aParams = array(':session_id' => $sessionID)
$sessionRow = $stmnt->fetch();
if ($sessionRow) {
// User is logged in, and you have details in $sessionRow
// At this point, you can also validate other info such as the UserAgent, IP etc. All forgable, but can help add a littel security.
} else {
// Passed an invalid / expired session ID
$sessionID = false;
}
}
// If you don't have a session, create one
if (!$sessionID) {
// Create a session ID - make it non sequential
// You should put this in a loop and check $sessionID is unique. Insert will fail is not unique
$sessionID = md5(time() . uniqid());
$sql = 'INSERT INTO sessions(session_id, teacher_id)
VALUES(:session_id, 0)';
$aParams = array(':session_id' => $sessionID)
$smnt->execute();
// Default session details
$sessionRow = array('teacher_id'=>0);
// Now the cookie part
setcookie('sessionID', $sessionID, time() + howLongYouWant, '/');
}
// Not check for user logging in.
if (UserLogsIn) {
if ($sessionRow['teacher_id'] > 0) {
// Already logged in!?
} else {
$sql = 'UPDATE sessions SET teacher_id=:teacher_id WHERE session_id=:session_id';
$aParams = array(':teacher_id'=>$teacher_id, ':session_id' => $sessionID);
$smnt->execute();
// After a form post, always redirect to the same page or another page - stops the "do you want to resent this data" message on back button
// DO NOT echo anything before this point.
header('location: this page');
exit();
}
} elseif (UserLogsOut) {
if ($sessionRow['teacher_id'] == 0) {
// Not Logged In!?
} else {
$sql = 'UPDATE sessions SET teacher_id=0 WHERE session_id=:session_id';
$aParams = array(':session_id' => $sessionID);
$smnt->execute();
// After a form post, always redirect to the same page or another page - stops the "do you want to resent this data" message on back button
// DO NOT echo anything before this point.
header('location: this page');
exit();
}
}
答案 1 :(得分:0)
我建议延长会话到期时间。通常会话在浏览器关闭时到期,您可以从ini设置更改此设置。见http://php.net/manual/en/session.configuration.php 不是你正在寻找的,即永远,但延长时间可能是一个合理的解决方案。