如何改进此用户名/密码检查?
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Login(FormCollection collection)
{
var users =
(from p in _dataContext.Users
where p.Name == collection["Username"] && p.Password == collection["Password"]
select p);
if (users.Count() > 0)
{
// Login Succeed
// To get the username I should do something like users.First().Name
// and that's really bad...
return RedirectToAction("Login");
}
else
{
// Login Faild
return View();
}
}
答案 0 :(得分:9)
您是否考虑过Microsoft的Membership API?它以安全的方式为您处理用户名和密码的所有详细信息。此外,您似乎计划以明文形式存储密码,这在密码学领域是cardinal sin。
答案 1 :(得分:2)
答案 2 :(得分:1)
我假设该查询只能有一个结果。如果是这样,您应该使用SingleOrDefault
:
var user = _dataContext.Users.SingleOrDefault(p =>
p.Name == collection["Username"]
&& p.Password == collection["Password"]);
if(user != null)
{
// Go on...
return RedirectToAction("Login");
}
else
{
// Login Faild
return View();
}
正如其他人所指出的那样,你应该在该代码中解决其他问题(即不存储纯文本密码而是存储哈希)。
答案 3 :(得分:0)
假设您的“用户名”字段保证是唯一的(即主键),只需选择用户并比较密码字段。
此外,您通常不应将原始密码存储在数据库中。相反,支持MD5哈希或其他东西(可能使用用户名作为盐)。然后将用户输入的哈希值与DB中的值进行比较,而不是比较原始值。
答案 4 :(得分:0)
与大多数人提到的一样,要么使用已提供的Membership API,要么以某种安全的方式加密密码。此外,如果您决定不选择加密密码,请确保使用已知可用的已建立加密库。
重新加密算法可能存在危险的缺陷(更不用说浪费时间,因为没有增加任何价值)如果做得不对。如果密码被泄露,那么不仅有人可以利用您的网站,而且可能还有许多其他网站,因为人们倾向于使用相同的用户名和密码。
最后,在.Net命令行中使用aspnet_regsql.exe来配置具有Membership API架构的数据库。实际上,配置数据库并切换web.config只需不到5分钟。