Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing "Remember Me" Feature in ASP.NET MVC

I'm trying to implement a "remember me" feature to my login form. I am using ASP.NET MVC as my web application. I managed to get the cookie stuff working, but I failed to automatically login the user in case he/she checked the remember me checkbox before. I know what the problem is but I do not know how to solve it.

In my HomeController I have the following:

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

And in my UserController, I have the Login action method:

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

So basically, what I thought I would do is to redirect the user from the Index action result on the home controller in case there was a login cookie. But the problem is that the RedirectToAction will trigger the GET Login action method and not the POST which takes care of logging in the user.

Am I going completely wrong about this? Or is there some way I could call the POST Login method using RedirectToAction or any other way?

like image 733
Kassem Avatar asked Apr 11 '11 10:04

Kassem


People also ask

How Remember Me works in ASP NET MVC?

Stored Procedure to Validate the User Credentials If the username and password are correct but the user has not been activated then the code returned is -2. If the username and password are correct and the user account has been activated then UserId of the user is returned by the stored procedure.

What is form authentication in MVC?

In order to implement the Forms Authentication in MVC application, we need to do the following three things. Set the Authentication mode as Forms in the web.config file. We need to use FormsAuthentication.SetAuthCookie for login. Again we need to use FormAuthentication.SignOut for logout.

What is enum in MVC?

The MVC framework sees the enum value as a simple primitive and uses the default string template. One solution to change the default framework behavior is to write a custom model metadata provider and implement GetMetadataForProperty to use a template with the name of "Enum" for such models.


1 Answers

First off, you should never store the user's credentials in a cookie. It's incredibly insecure. The password will be passed with every request as well as being stored in plain text on the user's machine.

Second, don't reinvent the wheel, especially when security is concerned, you'll never get it right.

ASP.Net already provides this functionality securely with Forms Authenitcation and Membership Providers. You should take a look into that. Creating a default MVC project will include the basic authentication setup. The official MVC site has more.

Update

You can still use .NET forms authentication without implementing a membership provider. At a basic level it would work like this.

You enable forms authentication in you web.config

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

You decorate the actions or the controllers you would like to secure with the [Authorize] attribute.

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

Then create a basic login action

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

  }

}
like image 192
David Glenn Avatar answered Oct 07 '22 22:10

David Glenn