Реализация функции «Запомни меня» в ASP.NET MVC

#asp.net-mvc #asp.net-mvc-3 #asp.net-mvc-routing #remember-me

#asp.net-mvc #asp.net-mvc-3 #asp.net-mvc-routing #запомни-меня

Вопрос:

Я пытаюсь внедрить функцию «запомнить меня» в свою форму входа. Я использую ASP.NET MVC как мое веб-приложение. Мне удалось заставить работать файлы cookie, но мне не удалось автоматически войти в систему пользователя, если он / она ранее установил флажок «Запомнить меня». Я знаю, в чем проблема, но я не знаю, как ее решить.

В моем HomeController у меня есть следующее:

 private LoginViewModel CheckLoginCookie()
{
    if (!string.IsNullOrEmpty(_appCookies.Email) amp;amp; !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);
}
  

И в моем пользовательском контроллере у меня есть метод Login action:

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

Итак, в принципе, я думал, что я сделаю, это перенаправлю пользователя из результата действия Index на домашнем контроллере в случае, если был файл cookie для входа. Но проблема в том, что RedirectToAction запустит метод GET Login action, а не POST, который заботится о входе пользователя в систему.

Я совершенно ошибаюсь в этом? Или есть какой-то способ, которым я мог бы вызвать метод POST Login, используя RedirectToAction или любой другой способ?

Ответ №1:

Во-первых, вы никогда не должны хранить учетные данные пользователя в файле cookie. Это невероятно небезопасно. Пароль будет передаваться с каждым запросом, а также сохраняться в виде обычного текста на компьютере пользователя.

Во-вторых, не изобретайте велосипед, особенно когда речь идет о безопасности, вы никогда не сделаете это правильно.

ASP.Net уже надежно предоставляет эту функциональность с помощью Forms Authenticitcation и поставщиков членства. Вам следует взглянуть на это. Создание проекта MVC по умолчанию будет включать базовую настройку аутентификации. На официальном сайте MVC есть больше.

Обновить

Вы все еще можете использовать .Аутентификация в сетевых формах без внедрения поставщика членства. На базовом уровне это будет работать следующим образом.

Вы включаете аутентификацию форм в своем 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");

  }

}
  

Комментарии:

1. 1 специально для создания проекта mvc по умолчанию. Если у меня есть какой-либо проект, которому требуется функция входа в систему, я создаю новое интернет-приложение mvc, а затем изменяю код оттуда.

2. @David Glenn: Я полностью понимаю, но я уже проходил через это, когда впервые начал работать над этим проектом и решил не использовать ASP.NET API членства, потому что он громоздкий, уродливый и не соответствует моим потребностям. Кроме того, я использую EF Code First в качестве моего ORM, поэтому я не смог найти способ работать с API членства и генерировать базу данных с помощью кода. В любом случае, если я не собираюсь хранить учетные данные в файле cookie, как мне реализовать функцию «Запомнить меня»?

3. @Rory McCrossan: пожалуйста, не сохраняйте идентификатор пользователя в файле cookie. Пользователю требуется несколько кликов, чтобы отредактировать этот файл cookie и авторизоваться как другой пользователь.

4. Мне пришлось добавить это, чтобы она работала правильно: if (authTicket. Сохраняется) { cookie. Срок действия = authTicket. Истечение срока действия; } Непосредственно перед добавлением файла cookie в ответ

5. Может, кто-нибудь подскажет мне, как проверить файлы cookie при повторном открытии сайта?