在ASP.NET MVC中实现"记住我"功能

Kas*_*sem 23 asp.net-mvc asp.net-mvc-routing remember-me asp.net-mvc-3

我正在尝试在登录表单中实现"记住我"功能.我使用ASP.NET MVC作为我的Web应用程序.我设法让cookie的东西工作,但我没有自动登录用户,以防他/她之前检查记住我复选框.我知道问题是什么,但我不知道如何解决它.

在我的HomeController中,我有以下内容:

private LoginViewModel CheckLoginCookie()
{
    if (!string.IsNullOrEmpty(_appCookies.Email) && !string.IsNullOrEmpty(_appCookies.Password))
    {
        var login = new LoginViewModel
                        {
                            Email = _appCookies.Email,
                            Password = _appCookies.Password
                        };

        return login;
    }
    return null;
}


public ActionResult Index()
{
    var login = CheckLoginCookie();
    if (login != null)
        return RedirectToAction("Login", "User", login);

    var viewModel = new HomeIndexViewModel
                        {
                            IntroText =
                                "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
                            LastMinuteDeals = new List<ItemsIndexViewModel>(),
                            TrustedDeals = new List<ItemsIndexViewModel>()
                        };
    return View(viewModel);
}
Run Code Online (Sandbox Code Playgroud)

在我的UserController中,我有Login操作方法:

public ActionResult Login()
{
    return PartialView(new LoginViewModel());
}

[HttpPost]
public ActionResult Login(LoginViewModel dto)
{
    bool flag = false;
    if (ModelState.IsValid)
    {
        if (_userService.AuthenticateUser(dto.Email, dto.Password, false)) {
            var user = _userService.GetUserByEmail(dto.Email);
            var uSession = new UserSession
            {
                ID = user.Id,
                Nickname = user.Nickname
            };
            SessionManager.RegisterSession(SessionKeys.User, uSession);
            flag = true;

            if(dto.RememberMe)
            {
                _appCookies.Email = dto.Email;
                _appCookies.Password = dto.Password;
            }
        }
    }
    if (flag)
        return RedirectToAction("Index", "Home");
    else
    {
        ViewData.Add("InvalidLogin", "The login info you provided were incorrect.");
        return View(dto);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以基本上,我认为我会做的是将用户从主控制器上的Index操作结果重定向,以防有登录cookie.但问题是RedirectToAction将触发GET Login操作方法,而不是POST负责登录用户的POST.

我对此完全错了吗?或者有什么方法可以使用RedirectToAction或任何其他方式调用POST登录方法?

Dav*_*enn 55

首先,您不应该将用户的凭据存储在cookie中.这是非常不安全的.密码将随每个请求一起传递,并以明文形式存储在用户的计算机上.

其次,不要重新发明轮子,特别是在安全方面,你永远不会做对.

ASP.Net已经通过Forms Authenitcation和Membership Providers安全地提供此功能.你应该看一下.创建默认MVC项目将包括基本身份验证设置.官方MVC网站有更多.

更新

您仍然可以使用.NET表单身份验证而无需实现成员资格提供程 在基础层面,它会像这样工作.

您在web.config中启用表单身份验证

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Run Code Online (Sandbox Code Playgroud)

您可以使用[Authorize]属性修饰要保护的操作或控制器.

[Authorize]
public ViewResult Index() {
  //you action logic here
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个基本的登录操作

[HttpPost]
public ActionResult Login(LoginViewModel dto) {

  //you authorisation logic here
  if (userAutherised) {
    //create the authentication ticket
    var authTicket = new FormsAuthenticationTicket(
      1,
      userId,  //user id
      DateTime.Now,
      DateTime.Now.AddMinutes(20),  // expiry
      rememberMe,  //true to remember
      "", //roles 
      "/"
    );

    //encrypt the ticket and add it to a cookie
    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,   FormsAuthentication.Encrypt(authTicket));
    Response.Cookies.Add(cookie);

    return RedirectToAction("Index");

  }

}
Run Code Online (Sandbox Code Playgroud)

  • @Rory McCrossan:请不要将用户ID存储在cookie中.用户只需点击几下即可编辑该Cookie并让自己以其他用户身份登录. (18认同)
  • 我必须添加它才能正常工作:if(authTicket.IsPersistent){cookie.Expires = authTicket.Expiration; 就在将cookie添加到响应之前 (5认同)
  • +1尤其适用于创建默认的mvc项目.如果我有任何需要登录功能的项目,我会创建一个新的mvc互联网应用程序,然后从那里更改代码. (2认同)