2009-11-03 121 views
0

如何改進此用戶名/密碼檢查?用戶名/密碼數據庫檢查

[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(); 
     } 
    } 

回答

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(); 

}

正如其他人所指出的,還有你應該在代碼解決其他問題(即,不存儲明文密碼,但散列)。

+0

我並不是真的期待這是被接受的答案。不要忘記做哈希事情。加鹽。你真的應該。 – 2009-11-04 13:50:24

+0

@Martinho - 對我有意義。許多人聽到「會員API」,並認爲「哦,不,另一個笨拙的框架」。我知道我第一次看到它。只有當現有的應用程序迫使我去使用它時,我才意識到它的優點。你回答了@Alon提出的問題。 – 2009-11-04 16:02:26

9

你認爲微軟的Membership API?它以安全的方式處理用戶名和密碼的所有細節。此外,它看起來像你計劃在密碼存儲密碼,這是在加密領域的cardinal sin

0

假設您的「用戶名」字段保證是唯一的(即主鍵),只需選擇用戶並比較密碼字段即可。

此外,您通常不應將原始密碼存儲在您的數據庫中。相反,支持MD5散列或其他東西(也許使用用戶名作爲鹽)。然後將用戶輸入的散列值與數據庫中的值進行比較,而不是比較原始值。

+0

MD5有一些缺點,不推薦使用它。我會推薦SHA1或SHA2。 – 2009-11-03 16:52:04

2
  1. 使用asp.net會員模型,不要重新發明輪子。
  2. 如果你真的想重新發明輪子,你需要醃製和散列密碼。只存儲密碼+鹽的散列。這是最少的。
0

像大多數人所說的那樣,要麼使用已經提供的Membership API,要麼以一些安全的方式加密密碼。另外,如果您決定不走這條路線並選擇加密密碼,請確保使用您熟悉的已建立的加密庫。

如果做得不好,重新創建加密算法可能存在危險的缺陷(更不用說浪費時間,因爲沒有值會被添加)。如果密碼被泄露,那麼不僅有人可以利用您的網站,而且可能還有很多其他網站,因爲人們傾向於使用相同的用戶名和密碼。

最後,在.Net命令行中使用aspnet_regsql.exe來爲Membership API配置一個數據庫模式。它實際上用不到5分鐘來配置數據庫並切換你的web.config。

+0

使用雙向加密技術存儲密碼也不是一個好主意。單向算法(哈希)更安全。 – 2009-11-04 13:51:59

+0

是的。作爲一般規則,如果您不需要知道該值,請對其進行哈希處理。 – jamesmillerio 2009-11-05 03:02:59