所以我正在登录使用JSON字符串来回读文件的游戏系统,但是当我哈希密码并尝试登录时它不起作用,但是当密码是未共享时它工作正常,我认为问题在于密码验证部分。
我只是不确定在哪里放置它,如果有人可以引导我朝着正确的方向,这将是惊人的......
所以问题是当我发送$ password示例test5时它只读作测试5而不是$ 2 $ 10 $ $ viov5WbMukXsCAfIJUTUZetGrhKE9rXW.mAH5F7m1iYGfxyQzQwD。
这是原始代码
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
$mysqli->close();
}
然后我尝试了这个
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$GetPassword = "SELECT password FROM users WHERE username='$username'";
$data = mysqli_query($GetPassword);
if(password_verify($password, $data['password'])) {
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
} else {
// password is in-correct
}
$mysqli->close();
}
答案 0 :(得分:2)
$data = mysqli_query($GetPassword);
^^^---mysqli result handle/object
if(password_verify($password, $data['password'])) {
^^^^^^^^^^^^---no such element in mysqli
您从未提取过数据结果,因此您需要将输入的密码与$data
结果对象/句柄的不存在元素进行比较。
你需要
$row = mysqli_fetch_assoc($data);
password_verify(..., $row['password']);
您很可能在禁用error_reporting和display_errors的情况下运行,这意味着您永远不会看到&#34;未定义的索引&#34;警告每次运行此代码时PHP都会抛出。这些设置永远不应该在开发/调试系统上关闭。
请注意,您很容易受到sql injection attacks的影响,因此您的安全&#34;系统不是 - 它完全没用,而且可以轻易绕过。
答案 1 :(得分:1)
您的代码存在一些问题,例如:
此声明$data = mysqli_query($GetPassword)
错误。 mysqli_query()
期望第一个参数是你的连接处理程序,所以应该是,
$data = mysqli_query($mysqli, $GetPassword);
看一下这句话,if(password_verify($password, $data['password'])) { ...
成功时,mysqli_query()
会返回结果集,因此您无法使用$data['password']
获取密码。首先从结果集中获取行,然后获取密码,如下所示,
$row = mysqli_fetch_assoc($data);
if(password_verify($password, $row['password'])) { ...
查看以下查询
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
由于此WHERE
条件...password='$password'
,此查询不会返回任何行。因此,解决方案是使用仅一个查询来验证密码并检索相关数据,而不是使用两个单独的查询。解决方案如下所示。
您的查询易受SQL injection影响。始终准备,绑定并执行您的查询prevent any kind of SQL injection。
如果您想构建一个json字符串,而不是echo "{"; echo '"result": "success",'; ...
,请创建一个包含所有相关数据的数组,然后json_encode
数组。
所以解决方案会是这样的:
// your code
$username = $_GET["user"];
$password = $_GET["password"];
// create a prepared statement
$stmt = mysqli_prepare($mysqli, "SELECT username, password, regkey, banned FROM users WHERE username=?");
// bind parameters
mysqli_stmt_bind_param($stmt, 's', $username);
// execute query
mysqli_stmt_execute($stmt);
// store result
mysqli_stmt_store_result($stmt);
// check whether the SELECT query returned any row or not
if(mysqli_stmt_num_rows($stmt)){
// bind result variables
mysqli_stmt_bind_result($stmt, $username, $hashed_password, $regkey, $banned);
// fetch value
mysqli_stmt_fetch($stmt);
if(password_verify($password, $hashed_password)){
echo json_encode(array('result' => 'success', 'regkey' => $regkey, 'banned' => $banned));
}else{
// incorrect password
}
}else{
// no results found
}
mysqli_stmt_close($stmt);
// your code