gpt4 book ai didi

c# - 如何实现密码重置链接

转载 作者:可可西里 更新时间:2023-11-01 08:16:58 24 4
gpt4 key购买 nike

我目前有一个系统,如果用户忘记了密码,他们可以通过单击忘记密码链接来重置密码。他们将被带到一个页面,在那里他们输入他们的用户名/电子邮件,然后一封电子邮件将发送给用户,我想知道如何在电子邮件中实现密码重置链接,以便一旦用户点击链接他/她被带到一个允许他们重置密码的页面。

这是我 Controller 中的代码

public ActionResult ForgotPassword()
{
//verify user id

string UserId = Request.Params ["txtUserName"];
string msg = "";
if (UserId == null)
{
msg = "You Have Entered An Invalid UserId - Try Again";
ViewData["ForgotPassword"] = msg;
return View("ForgotPassword");
}

SqlConnection lsql = null;
lsql = DBFactory.GetInstance().getMyConnection();

String sqlstring = "SELECT * from dbo.[USERS] where USERID = '" + UserId.ToString() + "'";
SqlCommand myCommand = new SqlCommand(sqlstring, lsql);
lsql.Open();
Boolean validUser;
using (SqlDataReader myReader = myCommand.ExecuteReader())
{

validUser = false;
while (myReader.Read())
{
validUser = true;

}
myReader.Close();
}
myCommand.Dispose();


if (!validUser)
{
msg = "You Have Entered An Invalid UserId - Try Again";
ViewData["ForgotPassword"] = msg;
lsql.Close();
return View("ForgotPassword");
}

//run store procedure


using (lsql)
{
SqlCommand cmd = new SqlCommand("Stock_Check_Test.dbo.RESET_PASSWORD", lsql);
cmd.CommandType = CommandType.StoredProcedure;

SqlParameter paramUsername = new SqlParameter("@var1", UserId);

cmd.Parameters.Add(paramUsername);


SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
if (Convert.ToInt32(rdr["RC"]) == 99)
{
msg = "Unable to update password at this time";
ViewData["ForgotPassword"] = msg;
lsql.Close();
return View("ForgotPassword");

}
}
}


msg = "new password sent";
ViewData["ForgotPassword"] = msg;
lsql.Close();
return View("ForgotPassword");
}

这是我当前向用户发送电子邮件的存储过程

ALTER PROCEDURE [dbo].[A_SEND_MAIL]
@var1 varchar (200), -- userid
@var2 varchar (200) -- email address
AS
BEGIN
declare @bodytext varchar(200);
set @bodytext = 'Password Reset for user: ' +@var1 + ' @' + cast (getDate() as varchar) + ' ' ;
EXEC msdb.dbo.sp_send_dbmail
@profile_name='Test',
@recipients=@var2,
@subject='Password Reset',
@body=@bodytext
END

GO

最佳答案

创建一个结构如下的表

create table ResetTickets(
username varchar(200),
tokenHash varbinary(16),
expirationDate datetime,
tokenUsed bit)

然后在您的代码中,当用户单击重置密码按钮时,您将生成一个随机 token ,然后在该表中放入一个条目,其中包含该 token 的散列值和诸如 DATEADD(day, 1, GETDATE()) 并将该 token 值附加到您通过电子邮件发送给密码重置页面用户的 url。

www.example.com/passwordReset?username=Karan&token=ZB71yObR

在密码重置页面上,您获取传入的用户名和 token ,再次对 token 进行哈希处理,然后将其与 ResetTickets 表进行比较,如果到期日期尚未过去且 token 尚未已被使用,然后将用户带到一个页面,让他们输入新密码。

注意事项:

  1. 确保 token 过期,不要让两年前的电子邮件重置密码。
  2. 确保将 token 标记为已使用,不要让计算机的其他用户使用浏览器的历史记录来重置其他用户的密码。
  3. 确保您安全地生成随机 token 。不要使用 Rand 并使用它来生成 token ,同时重置的​​两个用户将获得相同的 token (我可以同时重置我的密码和您的密码然后使用我的 token 重置您的帐户)。而是制作静态 RNGCryptoServiceProvider并从中使用 GetBytes 方法,该类是线程安全的,因此您无需担心两个线程使用同一个实例。
  4. 一定要parameterize your queries . 在您当前的代码中,如果我输入了用户 ID '; delete dbo.[USERS] -- 它将删除数据库中的所有用户。有关如何修复它的更多信息,请参阅链接的 SO 帖子。
  5. 确保对 token 进行哈希处理,您的passwordReset 页面只接受未经哈希处理的版本,并且您绝不会将未经哈希处理的版本存储在任何地方(包括发送给用户的传出消息的电子邮件日志).这可以防止具有数据库读取权限的攻击者为其他用户制作 token ,读取电子邮件中发送的值,然后自己发送相同的值(并且可能获得可以做更多事情的管理员用户的访问权限而不仅仅是读取值)。

关于c# - 如何实现密码重置链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29011841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com