web-dev-qa-db-fra.com

Implémentation de la fonctionnalité "Remember Me" dans ASP.NET MVC

J'essaie d'implémenter une fonctionnalité "se souvenir de moi" dans mon formulaire de connexion. J'utilise ASP.NET MVC comme application Web. J'ai réussi à faire fonctionner les cookies, mais je n'ai pas réussi à me connecter automatiquement à l'utilisateur au cas où il/elle aurait coché la case Se souvenir de moi auparavant. Je sais quel est le problème mais je ne sais pas comment le résoudre.

Dans mon HomeController, j'ai les éléments suivants:

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

Et dans mon UserController, j'ai la méthode d'action de connexion:

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

Donc, fondamentalement, ce que je pensais faire serait de rediriger l'utilisateur du résultat de l'action Index sur le contrôleur domestique au cas où il y aurait un cookie de connexion. Mais le problème est que le RedirectToAction déclenchera la méthode d'action GET Login et non le POST qui s'occupe de la connexion de l'utilisateur.

Suis-je complètement dans l'erreur? Ou existe-t-il un moyen d'appeler la méthode de connexion POST en utilisant RedirectToAction ou toute autre manière?

22
Kassem

Tout d'abord, vous ne devez jamais stocker les informations d'identification de l'utilisateur dans un cookie. C'est incroyablement précaire. Le mot de passe sera transmis à chaque demande et stocké en texte brut sur la machine de l'utilisateur.

Deuxièmement, ne réinventez pas la roue, surtout en matière de sécurité, vous ne réussirez jamais.

ASP.Net fournit déjà cette fonctionnalité en toute sécurité avec les fournisseurs d'authentification et d'adhésion aux formulaires. Vous devriez jeter un œil à cela. La création d'un projet MVC par défaut inclura la configuration d'authentification de base. L'officiel site MVC en a plus.

Mise à jour

Vous pouvez toujours utiliser l'authentification par formulaire .NET sans implémenter un fournisseur d'appartenance. Au niveau de base, cela fonctionnerait comme ça.

Vous activez l'authentification par formulaire dans votre web.config

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

Vous décorez les actions ou les contrôleurs que vous souhaitez sécuriser avec le [Authorize] attribut.

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

Créez ensuite une action de connexion de base

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

  }

}
54
David Glenn