在我的网站上,我完美地记录了用户,但我注意到当用户退出时,他们可以直接点击退格并重新登录,甚至只是将文件名放在URL中。我在这个问题上发现了很多问题,但有些问题非常模糊,步骤很少,而其他问题则非常过时。我基本上想给用户一个会话令牌,我已经生成并设置到数据库,并且该令牌将在URL中看作GET安全请求,但我不知道如何解决这个问题。这是我的登录页面和上传页面的代码
PHP登录页面
<?php
session_start();
if($_SERVER['REQUEST_METHOD'] =="POST"){
$username = trim($_POST['username']);
$password = trim($_POST['password']);
if(!empty($username) && !empty($password)){
try{
// new php data object
$handler = new PDO('mysql:host=127.0.0.1;dbname=magicsever', 'root', '');
//ATTR_ERRMODE set to exception
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
die("There was an error connecting to the database");
}
$stmt = $handler->prepare("SELECT * FROM generalusersdata WHERE username = :username");
$stmt->execute(array(':username'=>$username));
if($result = $stmt->fetch()){
if(password_verify($password, $result['password'])){
$token = md5(uniqid(mt_rand(), true));
$stmtToken = $handler->prepare("SELECT * FROM token_table WHERE token = :token");
$stmtToken->execute(array(':token'=>$token));
if($rowToken = $stmtToken->fetch()){
die("Error, Please try again");
}
$userid = $result['user_id'];
$email = $result['email'];
$time = time();
$stmtSendToken = $handler->prepare("INSERT INTO token_table set timestamp=?, user_id=?, token=?");
$stmtSendToken->execute(array($time, $userid, $token));
$stmtUpdate = $handler->prepare("UPDATE generalusersdata SET isDev = true WHERE user_id =?");
$stmtUpdate->execute(array($userid));
$_SESSION['id'] = $userid;
$_SESSION['username'] = $username;
$_SESSION['email'] = $email;
$_SESSION['timestamp'] = $time;
header("Location: developerUpload.php");
}
}else{
die("Username OR Password is incorrect! Please try again");
}
}else{
die("Values Missing!");
}
}
?>
登录后的PHP上传页面
<?php
session_start();
if(array_key_exists("id", $_COOKIE)){
//set the session id equal to the cookie
$_SESSION['id']= $_COOKIE['id'];
}
if(array_key_exists("id", $_SESSION)){
$username = $_SESSION['username'];
echo "Welcome To the Developer Side ".$username."!";
echo "<br><br><button><a href='developerLogin.php?logout=1'>Log Out</a></button></br></br>";
if(isset($_FILES['file']) && $_FILES['file']['size'] > 0){
$target = "devFiles/";
$target_file = addslashes(trim($target . basename($_FILES["file"]["name"])));
// Check file size not > 500Mb
if($_FILES["file"]["size"] > 500000000){
echo "Files Cannot be bigger than 500MB";
exit;
}
if(move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)){
try{
// new php data object
$handler = new PDO('mysql:host=127.0.0.1;dbname=magicsever', 'root', '');
//ATTR_ERRMODE set to exception
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
die("There was an error connecting to the database");
}
$dev_file = addslashes(trim($_FILES['file']['tmp_name']));
$file_name = addslashes(trim($_FILES['file']['name']));
$username = $_SESSION['username'];
$email = $_SESSION['email'];
$userid = $_SESSION['id'];
$time = $_SESSION['timestamp'];
$stmt = $handler->prepare("INSERT INTO developerfiles set user_id=?, username=?, email=?, dev_file=?, file_name=?, timestamp=?");
if(!$stmt->execute(array($userid, $username, $email, $dev_file, $file_name, $time))){
die("Error");
}else{
echo "Thank you for Submiting!";
}
}
}
}else {
header("Location: developerLogin.php");
}
?>
答案 0 :(得分:-1)
在您的上传文件中,您没有再次检查会话。
因此,每个人都可以登录您的上传文件,只创建$_SESSSION['id']='1'
和$_COOKIE['id']='1'
并登录(如果ID不存在,也是如此)。
还有一个tipp:在你的_SESSION中设置一个Hash(md5,uniqueid,...)或者类似的东西(来自你的数据库,有一个id),或者每个用户都可以登录,只更改_SESSION id。
另一件事是,您没有在洞脚本中设置_COOKIE
,但在上传文件中检查是否设置了_COOKIE
,或者删除了上传文件中的_COOKIE检查< / p>
因此,也要在您的登录页面添加setcookie()
,以便使用当前文件。
并向上传文件添加第二个SQL请求,例如:
$id=$_SESSION['id'];
if(!is_numeric($id) or $id<1) $id = 0; // a little bit of "security".
"SELECT * WHERE `id`='$id'";
if($sql_request => true){
// write the script
} else {
// you are not logged in
}
要销毁_SESSION(注销),请将_SESSION设置为$_SESSION['id']='empty'; unset($_SESSION['id']);
,这样就没有人可以使用后退按钮进行登录。
因此,您无需在网址中使用令牌进行保存。