我希望在我的网站上实现忘记密码功能。我喜欢将包含临时一次性使用 URL 的电子邮件发送给用户的选项,该 URL 在一段时间后过期。
我查看了以下页面以获得这些想法,但我不确定如何使用 ASP.NET 和 C# 来实现它。正如其中一位用户所指出的,如果我可以在不将此信息存储在数据库中的情况下实现这一点,那将是理想的。请指教。
谢谢。
我希望在我的网站上实现忘记密码功能。我喜欢将包含临时一次性使用 URL 的电子邮件发送给用户的选项,该 URL 在一段时间后过期。
我查看了以下页面以获得这些想法,但我不确定如何使用 ASP.NET 和 C# 来实现它。正如其中一位用户所指出的,如果我可以在不将此信息存储在数据库中的情况下实现这一点,那将是理想的。请指教。
谢谢。
可能最简单的方法是修改您的用户表以添加 2 个额外的列,或者如果您不想修改现有表,您可以添加一个名为“UserPasswordReset”的新依赖表或类似的东西。列是这样的:
PasswordResetToken UNIQUEIDENTIFIER,
PasswordResetExpiration DATETIME
如果您使用附加表路由,您还可以添加 UserID 列,将其作为主键和外键引用返回到您的用户表。还建议使用 UNIQUE 约束。然后,您只需在您的 asp.net 应用程序中使用 Guid 作为令牌。
流程可能是这样的:
我知道您想避免修改数据库,但这确实可能是最简单的方法。
@亚历克斯
您还可以将 .NET 中的 System.Security.Cryptography 类用于哈希算法。例如:
using System.Security.Cryptography;
...
var hash = SHA256CryptoServiceProvider.Create().ComputeHash(myTokenToHash);
...
在这里,您朋友中的 System.Guid 类,因为它将生成一个唯一(嗯,足够唯一)128 位数字:
我使用哈希类创建由当前日期/时间和用户电子邮件地址组成的唯一自动登录:
string strNow = DateTime.Now.ToString();
string strHash = strNow + strEmail;
strHash = Hash.GetHash(strHash, Hash.HashType.SHA1);
从以下位置获取哈希类:http: //www.developerfusion.com/code/4601/create-hashes-md5-sha1-sha256-sha384-sha512/
然后只需使用以下 URL 从 URL 中获取它:
if (Request.QueryString["hash"] != null)
{
//extract Hash from the URL
string strHash = Request.QueryString["hash"];
}
我肯定会在这个过程中包括数据库。一旦请求重置,最好表明该帐户已被锁定。
例如,如果您更改密码是因为您认为您的帐户可能已被盗用,那么您绝对不希望在进行更改过程时它仍然可以访问。
此外,如果有人真的想要它并且有能力,可以解码重置令牌中包含的“真实”信息。生成一个随机字符串会更安全,将其保存在该用户所在行的数据库中,然后在单击链接时将其键入。
这给了你两件事:
1)没有什么可以解密的,因此不能从中获得任何有价值的东西。2) 用户记录中存在令牌表示正在进行重置,应将帐户视为已锁定。
向用户电子邮件发送一些数据|字符串的目的是验证帐户所有者。请注意以下几点:
结果:我认为你最好
祝你好运。
我会使用哈希码来验证密码重置网址中的详细信息。这一切都可以在不向数据库写入任何内容或向攻击者发送任何特权信息的情况下完成。
简单解释一下普通密码盐和散列;假设 salt is1111
和 pasword is password
,您将连接两者并对字符串进行哈希处理1111password
,假设这给了您 的哈希值9999
,然后您将原始 salt1111
和哈希值存储9999
在您的用户记录中。
当您验证密码时,您使用存储的盐,连接密码尝试,对其进行散列并与存储的散列进行比较。例如asecret
变成1111asecret
但散列到8888
. 这与原始哈希不匹配,因此密码匹配失败。
当然,盐和哈希通常会使用已建立的加密库正确生成和计算(不要自己发明!)。
对于密码重置 URL,我会输入用户的唯一标识符,即电子邮件地址、发出请求的日期和新的哈希值。这个散列是从那些连接在一起的细节加上已经为用户存储的盐和散列生成的。
例如:
Email: user@example.com
Request Date: 2014-07-17
Salt: 1111
Hash: 9999
生成这些连接的新哈希,即'user@example.com2014-07-1711119999'
,假设这给出了 的哈希7777
。
然后我生成的 URL 将包含电子邮件、请求日期和新哈希:
https:\\www.example.com\ResetPassword?email=user@example.com&requestdate=2014-07-17&hash=7777
服务器会将电子邮件和提供的日期与它的盐和散列结合起来,并确认它生成的散列与提供的散列相同。如果这没问题,那么它将显示重置表单,其中隐藏了相同的三个参数,否则会出错。当输入新密码以防止该表单被欺骗时,这些将被重新提交并重新检查。
需要提供电子邮件地址才能提出请求,并且仅通过电子邮件将其发送到同一地址。日期几乎不是特权信息,而且哈希是不可逆的,所以无论如何都没有给出任何信息。没有向数据库写入任何内容,任何对参数的篡改都会导致哈希失败并且 URL 报告错误。
这种方法存在问题。安全的散列使令牌非常长。要么将盐集成到散列本身(使其长约 20 个字符),要么将这个唯一的盐存储在数据库中。如果您将盐存储在数据库中,您还可以存储一个随机令牌,该令牌不是从任何现有的
根据您的需要,您可以加密信息,格式类似于以下格式
(UserId)-(ExpireDate)
加密数据,建立链接,然后解密数据并从那里采取行动......
粗鲁,但很可能可用,并且不需要使用数据库