Php 多个数据库登录请求
我有三个文件与我的登录场景的这一部分相关:Php 多个数据库登录请求,php,function,authentication,Php,Function,Authentication,我有三个文件与我的登录场景的这一部分相关: /project/index.html /project/api/user/login.php /project/api/objects/user.php index.html中有一个简单的登录表单,调用./api/user/login.php。 在这个表单中,我有一个复选框,它是用户保持登录或不登录的选项 如果用户选择了此选项,则每次登录时,我都会检查凭据是否正确(user.php中的login function->stmt1),如果设置了复选框(u
/project/index.html
/project/api/user/login.php
/project/api/objects/user.php index.html中有一个简单的登录表单,调用./api/user/login.php。
在这个表单中,我有一个复选框,它是用户保持登录或不登录的选项 如果用户选择了此选项,则每次登录时,我都会检查凭据是否正确(user.php中的login function->stmt1),如果设置了复选框(user.php中的login function->stmt2),则会更新lastlogin(datetime)、标识符和securitytoken user.php包含在login.php中一次,它从index.html表单中获取值并将其发送到user.php中的login()函数。
根据函数返回值,login.php决定登录是否成功 登录本身(stmt1)可以工作,但lastlogin、identifier和securitytoken(stmt2)的更新不能工作 login.php
session_start();
// include database and object files
include_once '../config/database.php';
include_once '../objects/user.php';
// get database connection
$database = new Database();
$db = $database->getConnection();
// prepare user object
$user = new User($db);
// set ID property of user to be edited
$user->username = isset($_GET['username']) ? $_GET['username'] : die();
$user->password = base64_encode(isset($_GET['password']) ? $_GET['password'] : die());
$user->remember = isset($_GET['remember']) ? $_GET['remember'] : die();
$stmt1 = $user->login();
if($stmt1->rowCount() > 0){
// get retrieved row
$row1 = $stmt1->fetch(PDO::FETCH_ASSOC);
$_SESSION['userid'] = $row1['uid'];
// create array
$user_arr=array(
"status" => true,
"message" => "Login erfolgreich!",
"uid" => $row1['uid'],
"username" => $row1['username']
);
$stmt2 = $user->login();
$row2 = $stmt2->fetch(PDO::FETCH_ASSOC);
print_r($row2);
// create array
$user_arr=array(
"lastlogin" => $row2['lastlogin']
);
}
else{
$user_arr=array(
"status" => false,
"message" => "Benutzername und/oder Passwort nicht korrekt!",
);
}
// make it json format
print_r(json_encode($user_arr));
?>
user.php
function login(){
// select all query
$query1 = "SELECT
`uid`, `username`, `email`, `password`, `created`, `lastlogin`
FROM
" . $this->table_name . "
WHERE
username='".$this->username."' AND password='".$this->password."'";
// prepare query statement
$stmt1 = $this->conn->prepare($query1);
// execute query
$stmt1->execute();
return $stmt1;
// set up the remain logged in function
if(isset($this->remember)) {
$identifier = random_string();
$securitytoken = random_string();
$remember = ",identifier='".$identifier."',securitytoken='".$securitytoken."'";
setcookie("identifier",$identifier,time()+(3600*24*365)); //1 year valid
setcookie("securitytoken",$securitytoken,time()+(3600*24*365)); //1 year valid
} else {
$remember = "";
}
// update last login
$query2 = "UPDATE
" . $this->table_name . "
SET
`lastlogin` = '".date("Y-m-d H:i:s")."'
".$remember."
WHERE
username='".$this->username."' AND password='".$this->password."'";
// prepare query statement
$stmt2 = $this->conn->prepare($query2);
// execute query
$stmt2->execute();
return $stmt2;
}
function random_string(){
if(function_exists('random_bytes')) {
$bytes = random_bytes(16);
$str = bin2hex($bytes);
} else if(function_exists('openssl_random_pseudo_bytes')) {
$bytes = openssl_random_pseudo_bytes(16);
$str = bin2hex($bytes);
} else if(function_exists('mcrypt_create_iv')) {
$bytes = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$str = bin2hex($bytes);
} else {
//secret key should have >12 random chars
$str = md5(uniqid('SECRET KEY', true));
}
return $str;
}
在user.php中,返回$stmt1; 返回代码,但未设置cookie 我会这样做。。。检查登录。。。如果为true,则使用id和令牌保存cookie 然后定期检查令牌和id是否对应。。。如果是的话。。。只需更新上次登录时间
注意:您准备的声明易受攻击!!不要用“.”附加参数。请改用占位符,不要对密码进行编码,最好将其散列。。。然后比较散列以什么方式失败?正在执行的查询的运行时值是多少?这是你所期望的吗?您是否能够手动执行精确的复制/粘贴查询?还值得注意的是,您的代码对SQL注入是开放的,这既是一个安全漏洞,也是常见的bug源,后者可能正是这里发生的事情。失败的是,似乎只有stmt1(user.php)被传输到login.php。更新没有发生。在index.php中,我得到了一个包含stmt1所有信息的数组。这就好像stmt2查询被忽略了一样。感谢您提供的SQL注入提示。我正处于实施的开始阶段。我将强化代码,以防止SQL注入。“只是不发生”和“忽略某个地方”意味着所讨论的代码根本没有执行。您可以通过一些调试来确认这一点。即使不使用正式的调试器,也可以在整个代码中添加日志输出。例如,假设您有一个将字符串写入日志文件的通用函数。在整个代码中,您可以调用该函数,同时编写有用的信息。因此,在代码运行之后,您将有一个关于发生了什么的信息日志。简单的事情,如“转到第47行”或相关变量的值。更新查询中的
记住是什么???@David:当然,这是我尽力做到的。这就是为什么我可以说stmt2没有被执行,但我不能说为什么。