27

ログインフォームに「remember me」機能を実装しようとしています。Web アプリケーションとして ASP.NET MVC を使用しています。Cookie を機能させることはできましたが、ユーザーが以前に [remember me] チェックボックスをオンにした場合に備えて、ユーザーを自動的にログインさせることができませんでした。問題が何であるかはわかっていますが、それを解決する方法がわかりません。

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

基本的に、ログイン Cookie があった場合に備えて、ホーム コントローラーの Index アクションの結果からユーザーをリダイレクトすることを考えました。しかし問題は、RedirectToAction がユーザーのログインを処理する POST ではなく、GET Login アクション メソッドをトリガーすることです。

私はこれについて完全に間違っていますか?または、RedirectToAction またはその他の方法を使用して POST Login メソッドを呼び出す方法はありますか?

4

1 に答える 1

60

まず、ユーザーの資格情報をCookieに保存しないでください。それは信じられないほど安全ではありません。パスワードはすべてのリクエストで渡され、ユーザーのマシンにプレーンテキストで保存されます。

第二に、車輪の再発明をしないでください。特にセキュリティが懸念される場合は、正しく理解することはできません。

ASP.Netは、FormsAuthenitcationおよびMembershipProvidersでこの機能を既に安全に提供しています。あなたはそれを調べなければなりません。デフォルトの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");

  }

}
于 2011-04-11T10:34:14.170 に答える