在 MVC ASP.NET 实现"Remember Me"功能



我试图实现一个"记住我"的功能,我的登录表单。我用的是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);
}

在我的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);
    }
}

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

我完全错了吗?或者有一些方法我可以调用POST Login方法使用RedirectToAction或任何其他方式?

首先,永远不要将用户的凭据存储在cookie中。这是非常不安全的。密码将随每个请求一起传递,并以明文形式存储在用户的机器上。

第二,不要重新发明轮子,特别是当涉及到安全时,你永远不会做对的。

ASP。Net已经通过表单身份验证和成员资格提供程序安全地提供了此功能。你应该调查一下。创建默认MVC项目将包括基本的身份验证设置。MVC官方网站有更多。

更新

您仍然可以使用。net表单身份验证而不实现成员资格提供程序。在基本层面上,它是这样工作的。

在web.config

中启用表单认证
<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

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

[Authorize]
public ViewResult Index() {
  //you action logic here
}

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

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

最新更新