2014-09-24 24 views
5

Tôi tự hỏi nếu có một tuyến đường hiệu quả hơn để thực hiện ở đây. Sử dụng AspNet.Identity Tôi muốn cho phép người dùng đăng nhập vào cùng một hộp văn bản bằng cách sử dụng UserName hoặc Email của họ. Tôi đã tiếp tục và giải quyết vấn đề này trong số AccountController Login ActionResult. Tôi chạy kiểm tra trước khi gọi:Cho phép người dùng đăng nhập bằng Email HOẶC Tên người dùng (AspNet.Identity)

var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: true); 

Check:

//TODO: determine if there is a more efficient way to allow user to login either with Email || UserName 
if (model.UserName.Contains("@")) 
{ 
    using (var context = new ApplicationDbContext()) 
    { 
     model.UserName = (context.Users.Any(p => p.Email == model.UserName)) ? 
      context.Users.SingleOrDefault(p => p.Email == model.UserName).UserName : 
      model.UserName; 
    } 
} 

mối quan tâm của tôi ở đây là hai lần:

  1. là của họ một cách thiết thực hiệu quả hơn để làm điều này.
  2. Tôi có giới thiệu bất kỳ rủi ro bảo mật hoặc rủi ro hiệu suất mới nào bằng cách thực hiện theo cách này không?

Tôi bao gồm toàn bộ ActionResult bên dưới để tham khảo.

// 
// POST: /Account/Login 
[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(model); 
    } 

    //TODO: determine if there is a more efficient way to allow user to login either with Email || UserName 
    if (model.UserName.Contains("@")) 
    { 
     using (var context = new ApplicationDbContext()) 
     { 
      model.UserName = (context.Users.Any(p => p.Email == model.UserName)) ? 
       context.Users.SingleOrDefault(p => p.Email == model.UserName).UserName : 
       model.UserName; 
     } 
    } 

    // This doesn't count login failures towards account lockout 
    // To enable password failures to trigger account lockout, change to shouldLockout: true 
    var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: true); 
    switch (result) 
    { 
     case SignInStatus.Success: 
      return RedirectToLocal(returnUrl); 
     case SignInStatus.LockedOut: 
      return View("Lockout"); 
     case SignInStatus.RequiresVerification: 
      return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); 
     case SignInStatus.Failure: 
     default: 
      ModelState.AddModelError("", "Invalid login attempt."); 
      return View(model); 
    } 
} 

liên quan vấn đề github #2#4

+2

Bạn có thể bắt đầu bằng cách không kiểm tra xem mục nhập có '@' hay không. –

+0

@RedSerpent lý do tôi kiểm tra nếu mục nhập có '@' là vì tôi không muốn nhấn cơ sở dữ liệu với truy vấn LINQ 'context.Users.Any' nếu tôi không cần. Sẽ đánh cơ sở dữ liệu là một giải pháp tốt hơn? Bạn có vấn đề gì với việc kiểm tra '@'? – aaronmallen

+0

Tôi gặp vấn đề tương tự khi bắt đầu với Identity 1.0, tôi phải chèn các trường email và userName giống nhau. – DSR

Trả lời

8

Sẽ có một vấn đề an ninh. Bạn có thể lấy tên người dùng của người dùng khác nếu bạn biết email của mình:

  1. viết email của mình và mật khẩu sai
  2. thì hệ thống nạp tên người dùng tương ứng, thực hiện xác nhận mật khẩu đó bị lỗi và trả về mô hình với Tên truy nhập ghi đè

Tôi sẽ khai báo biến mới thay vì sử dụng lại mô hình.UserName. Và truy vấn của bạn sẽ hiệu quả hơn một chút nếu bạn sử dụng FirstOrDefault:

var userName = model.UserName; 
    using (var context = new ApplicationDbContext()) 
    { 
     var user = context.Users.FirstOrDefault(p => p.Email == model.UserName); 
     if (user != null) 
     { 
      userName = user.UserName; 
     } 
    } 

var result = await SignInManager.PasswordSignInAsync(userName, model.Password, model.RememberMe, shouldLockout: true); 
+0

Tất cả các điểm hợp lệ và tôi chắc chắn sẽ giới thiệu một số thay đổi đó. Tuy nhiên, điều này vẫn đang sử dụng về cơ bản cùng một phương thức mà tôi đã sử dụng, không có cách nào thường được thực hiện với 'AspNet.Identity'? – aaronmallen

+1

@aaronmallen tôi không biết nhưng tôi nghĩ rằng giải pháp của bạn là đủ tốt. –

Các vấn đề liên quan