【问题标题】:PHP Password Reset URL processingPHP密码重置URL处理
【发布时间】:2015-11-05 17:23:31
【问题描述】:

我如何(并且应该?)存储密码重置 URL 中的重置代码以处理密码重置?

简而言之,我正在尝试创建一个密码重置系统,用户在其中输入他们的电子邮件地址,该系统会生成一个随机重置代码,该代码附加到一个 URL,然后通过电子邮件发送给用户。

然后用户单击该链接并被带到密码重置页面。重置代码和电子邮件取自 URL 并存储在变量中。然后在提交新密码时使用这些变量来检查它们是否与数据库匹配,并且它们将更新密码。

我认为我遇到的问题是 reset.php 是用于“操作”新密码表单的页面,因此当提交新密码时,只有当页面首次从链接,即使这样,其余代码和电子邮件值似乎也没有存储在创建的变量中。

如何保留这些值以及我应该使用哪个 URL 来“操作”表单以确保它有效?我是否以完全错误的方式处理这个问题?

希望这是有道理的,有人可以提供帮助吗?请用简单的术语解释一下,因为我对 PHP 很陌生,尤其是在密码等方面。

缩短的代码(应该足够清楚看到问题):

<?php

require("../db_connect.php");
$page_title = "Password Reset";
$errors = array();

// check if reset code and email is set in URL and store in variable if it is
// example URL http://www.thissite.com/reset.php?reset=123abc&email=me@me.com

if (!isset($_GET['reset']) || (!isset($_GET['email']))
{ 
  //create error message and link to forgotten password page 
}

else

{ 
  $reset_from_url = mysqli_real_escape_string( $dbc , $_GET['reset'] );
  $email_from_url = mysqli_real_escape_string( $dbc , $_GET['email'] );
}

if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
{ 
  // code to compare reset code and email from URL with database
  // code to check passwords entered and if all ok, insert into database
}

<form action="reset.php" method="POST">
<p>New password:</p>
<input type = "password">
</p>Confirm Password:</p>
<input type = "password">
</form>

【问题讨论】:

  • 您很可能需要将重置代码和电子邮件作为隐藏字段存储在表单上,​​因此当您发回页面时,数据仍然存在。
  • 某处应该有数据库
  • @deluxes 我该怎么做呢?我已经尝试创建 但该变量在要处理的主要代码部分中仍然不可用?
  • @user4612360 你在考虑代码的“主要部分”。
  • @deluxes 代码的最上面部分打开了连接。接下来检查是否在页面加载时设置了值,然后在单击提交按钮时运行第三部分。所以我想说第三部分是主要部分,因为如果这有意义,每次提交表单时都会一遍又一遍地运行?我想我需要做的是从原始 url 中获取值,然后将它们存储在隐藏字段中,然后在提交表单时再次获取它们,但是考虑到上面的尝试不起作用,我该怎么做?跨度>

标签: php url passwords


【解决方案1】:

正如您已经尝试过的,您必须将来自 url 的令牌存储在隐藏字段中。

$tokenFromUrl = $_GET['reset'];
$escapedTokenFromUrl = htmlspecialchars($tokenFromUrl);
...
<form action="reset.php" method="POST">
  <input type="hidden" name="token" value="<?php echo $escapedTokenFromUrl; ?>" />
...
</form>

你使用了错误的转义函数,mysqli_real_escape_string() 是为了对数据库查询进行转义,并且只能在你有一个打开的数据库连接时使用。而是使用 htmlspecialchars() 转义 HTML 输出。

那么你的隐藏标签需要一个name属性,否则你不能在post请求中访问它。

最后但同样重要的是,您应该只在数据库中存储令牌的哈希值,否则对数据库具有读取权限的攻击者(SQL 注入)可以请求令牌并自己使用令牌来获取帐户。在这个小的article 中,我试图展示如何做到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2019-09-19
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 2013-03-23
    相关资源
    最近更新 更多