Php 无法检索用于密码重置的get变量

Php 无法检索用于密码重置的get变量,php,html,change-password,reset-password,Php,Html,Change Password,Reset Password,我已经建立了一个网站,现在我正在尝试创建一种方法,允许用户在忘记密码时重置密码。我已经成功创建了一个密码重置url链接,但每当我点击它时,就会收到一个“无效请求!”通知,而不是将我带到index.php页面。如果有人能帮忙,我将不胜感激。我的代码如下 resetpassword.php include ("connect.php"); //Connect to MySQL database using PDO. $pdo = new PDO("mysql:host=$host;dbn

我已经建立了一个网站,现在我正在尝试创建一种方法,允许用户在忘记密码时重置密码。我已经成功创建了一个密码重置url链接,但每当我点击它时,就会收到一个“无效请求!”通知,而不是将我带到index.php页面。如果有人能帮忙,我将不胜感激。我的代码如下

resetpassword.php
  include ("connect.php");

  //Connect to MySQL database using PDO.
 $pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pwd);

 //Get the name that is being searched for.
 $email = isset($_POST['email']) ? trim($_POST['email']) : '';

 //The simple SQL query that we will be running.
 $sql = "SELECT `id`, `email` FROM `registration` WHERE `email` = :email";

 //Prepare our SELECT statement.
 $statement = $pdo->prepare($sql);

 //Bind the $name variable to our :name parameter.
 $statement->bindValue(':email', $email);

 //Execute the SQL statement.
 $statement->execute();

//Fetch our result as an associative array.
$userInfo = $statement->fetch(PDO::FETCH_ASSOC);

//If $userInfo is empty, it means that the submitted email
//address has not been found in our users table.
if(empty($userInfo)){
echo 'That email address was not found in our system!';
exit;
}

//The user's email address and id.
$userEmail = $userInfo['email'];
$userId = $userInfo['id'];

//Create a secure token for this forgot password request.
$token = openssl_random_pseudo_bytes(16);
$token = bin2hex($token);

//Insert the request information
//into our password_reset_request table.

//The SQL statement.
$insertSql = "INSERT INTO password_reset_request
          (user_id, date_requested, token)
          VALUES
          (:user_id, :date_requested, :token)";

//Prepare our INSERT SQL statement.
$statement = $pdo->prepare($insertSql);

//Execute the statement and insert the data.
$statement->execute(array(
"user_id" => $userId,
"date_requested" => date("Y-m-d H:i:s"),
"token" => $token
));

//Get the ID of the row we just inserted.
$passwordRequestId = $pdo->lastInsertId();

 //Create a link to the URL that will verify the
 //forgot password request and allow the user to change their
 //password.
 $verifyScript = 'http://localhost/trial/pages/createpassword.php';

//The link that we will send the user via email.
$linkToSend = "<a href='$verifyScript'? 
uid='.$userId.'&id='.$passwordRequestId.'&t='.$token'>$verifyScript.'? 
uid='.$userId.'&id='.$passwordRequestId.'&t='.$token</a>";

//Print out the email for the sake of this tutorial.
echo $linkToSend;

?>
include ("connect.php");

//Connect to MySQL database using PDO.
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pwd);

//The user's id, which should be present in the GET variable "uid"
$userId = isset($_GET['uid']) ? trim($_GET['uid']) : '';
//The token for the request, which should be present in the GET variable "t"
$token = isset($_GET['t']) ? trim($_GET['t']) : '';
//The id for the request, which should be present in the GET variable "id"
$passwordRequestId = isset($_GET['id']) ? trim($_GET['id']) : '';

//Now, we need to query our password_reset_request table and
//make sure that the GET variables we received belong to
//a valid forgot password request.

$sql = "
  SELECT id, user_id, date_requested 
  FROM password_reset_request
  WHERE 
    user_id = :user_id AND 
    token = :token AND 
    id = :id
 ";

//Prepare our statement.
$statement = $pdo->prepare($sql);

 //Execute the statement using the variables we received.
 $statement->execute(array(
"user_id" => $userId,
"id" => $passwordRequestId,
"token" => $token
 ));

 //Fetch our result as an associative array.
 $requestInfo = $statement->fetch(PDO::FETCH_ASSOC);

 //If $requestInfo is empty, it means that this
 //is not a valid forgot password request. i.e. Somebody could be
 //changing GET values and trying to hack our
 //forgot password system.
 if(empty($requestInfo)){
 echo 'Invalid request!';
 exit;
 }

 //The request is valid, so give them a session variable
 //that gives them access to the reset password form.
 $_SESSION['user_id_reset_pass'] = $userId;

//Redirect them to your reset password form.
header('Location: index.php');
exit;

?>
修改此代码:

$linkToSend = "<a href='$verifyScript'? 
uid='.$userId.'&id='.$passwordRequestId.'&t='.$token'>$verifyScript.'? 
uid='.$userId.'&id='.$passwordRequestId.'&t='.$token</a>";
$linkToSend=”“;
致:

$linkToSend='';
或者简单地从字符串中删除意外点

$linkToSend = "<a href='$verifyScript'? 
uid='$userId'&id='$passwordRequestId'&t='$token'>$verifyScript'? 
uid='$userId'&id='$passwordRequestId'&t='$token</a>";
$linkToSend=”“;

据我所知,您的变量没有传递任何信息,因此可能是由于您的sql语句:

$requestInfo = $statement->fetch(PDO::FETCH_ASSOC);
我从未使用过PDO,因此不能100%确定,但请尝试以下方法:

$id = htmlentities($connect->real_escape_string($_GET['id']));
$userid = htmlentities($connect->real_escape_string($_GET['uid']));
$token = htmlentities($connect->real_escape_string($_GET['token']));

$sql = " SELECT * FROM password_reset_request WHERE user_id = '$userid' AND token = '$token' AND id = '$id' ";

您知道,
$vars
会自动展开为双引号字符串,对吗?这就是为什么OP在所有html属性周围使用单引号(相当合法)的原因,我担心您建议的更改会破坏html!是,解释带双引号的$VAR。但是,对于is字符串的构造,代码将返回这个值之王uid='.12',这就是为什么他得到错误无效请求的原因。如果您使用的是代码,则html无效。为了安全和性能,不要使用双引号在字符串中打印变量内容。是的,所以请按照您的建议进行更正。我很抱歉,我提出的解决方案是正确的。它将生成这样的字符串,例如:>安全地执行查询并使其在
MYSQLI\uuquot>或
PDO
API中广泛使用不是一个好主意我想这不是重点吧?我发表了评论,向他展示了一种解决他创建的错误查询中问题的方法。我没有教他安全标准……Gongas我还认为问题正如您所提到的,因为代码似乎在通知您无效请求时失败。但是你的解决方案对我不起作用。我真的不明白。我的代码如何受到sql注入攻击?你能指出漏洞在哪里吗?@Gongas你没有准备你的SQL查询,所以你的代码容易受到SQL注入之类的攻击。请不要使用你自己的密码哈希。PHP提供并请使用它们。如果您使用的是5.5之前的PHP版本,这里有一些
$requestInfo = $statement->fetch(PDO::FETCH_ASSOC);
$id = htmlentities($connect->real_escape_string($_GET['id']));
$userid = htmlentities($connect->real_escape_string($_GET['uid']));
$token = htmlentities($connect->real_escape_string($_GET['token']));

$sql = " SELECT * FROM password_reset_request WHERE user_id = '$userid' AND token = '$token' AND id = '$id' ";