好的,我正在通过做小项目来学习ASP.Net MVC 5。我正在实现忘记密码功能。这是流程:
现在所有这些页面都有各自的URL,页面应按此顺序打开。但是如果我在浏览器链接中输入可能是第3步(输入令牌)或第4步(输入新密码)的URL所需的URL,我可以打开相应的页面。但我不希望这样。如果有人不遵循步骤1到4,则他们无法直接打开任何无序URL。如何实现上述功能。
注意:如果我们在控制器操作中添加[Authorize]
属性,那么无论我们在浏览器中访问哪个URL,我们总会被重定向到登录页面(如果尚未登录)。我可以实现上述目标吗?因此,如果有人试图直接打开/VerifyToken
页面,那么他应该被重定向到页面/SendEmailForReceiveingToken
。
编辑1
好的,这就是事情。为了识别合适的人,我正在使用令牌。但是为了检查我的数据库中的令牌字段,我想要唯一地知道用户。为此,我正在使用电子邮件ID。所以基本上我用数据库ID查询数据库以找到用户,然后检查该行中的令牌集。但如果有人直接去验证令牌,那么我将无法知道他的电子邮件ID。截至目前,我将电子邮件作为token page
和resetpassword page
编辑2
所以在上午12:00,用户获得了令牌。但他没有继续使用"重置密码"。他在2分钟后到达并直接进入/VerifyToken
页面并输入令牌。所以现在我无法访问电子邮件ID。我现在如何验证令牌。我不想查询整个令牌列并匹配相应的行。
答案 0 :(得分:0)
任意用户打开没有任何问题,例如第3页,他应该输入有效的令牌。如果他之前没有收到过这样的有效令牌,并且您在下一步中对令牌进行了适当的验证,那么该用户就无法做任何有用的事情。你的设计太复杂了。
只需对实际密码重置发生的步骤进行适当的验证 - 验证是否输入了有效的令牌。只要令牌有效,提交此令牌的页面就无关紧要。
答案 1 :(得分:0)
您认为需要电子邮件地址以验证令牌是正确的。但是,您不需要为此目的建立刚性流。
您只需将电子邮件地址作为查询参数插入密码重置网址即可。示例网址:
http://www.example.com/resetpassword/ZXhhbXBsZQ?email=example@example.com
然后使用指定的电子邮件查询用户的标记。
或者您可以在步骤3或4中询问用户电子邮件。如果您查看Visual Studio创建的基于ASP.NET身份的默认项目,那么您将看到的内容。密码表单还要求用户输入他的电子邮件。
或者您也可以使用更高级的令牌,在该令牌中可以嵌入信息。例如,可以将用户主体嵌入到JWT令牌中。但是,我个人认为这对密码重置来说太过分了。一个明显的缺点是JWT令牌,因此您的密码重置URL将会更长。
答案 2 :(得分:0)
假设您的令牌实际上是唯一的,您实际上并不需要知道该用户的电子邮件地址/用户名。令牌充当用户记录的(临时)唯一ID,因此您只需将该令牌保留在"输入新密码"查看,并在重置逻辑中使用它:
public bool UpdatePasswordForToken(string token, string newPassword)
{
bool success = false;
var user = Context.Users.SingleOrDefault(u => u.ResetToken.Equals(token, StringComparison.OrdinalIgnoreCase));
if (user != null)
{
var password = Crypto.HashPassword(newPassword);
if (!string.IsNullOrWhiteSpace(password))
{
user.Password = password;
user.ResetToken = null;
Context.SaveChanges();
success = true;
}
}
return success;
}
这假设您不必在完成密码重置时将用户登录。我重定向到登录页面(带有成功消息)。即使有人设法猜出一个有效的重置令牌(这意味着令牌并不是真正独特的),他们也需要知道他们刚刚重置了哪个用户名,以便以(现在已被入侵的)用户身份登录。 / p>
如果您确实只是按照工作流程设置用户,那么显而易见的答案似乎是检查Request.UrlReferrer
值,并将用户从当前操作中反弹,如果它不是你想要采取行动这一行动。但是UrlReferrer并不是防弹的,所以我建议只是简化你的工作流程,就像我上面提到的那样。