实现“记住我"ASP.NET MVC 中的功能 [英] Implementing "Remember Me" Feature in ASP.NET MVC

查看:32
本文介绍了实现“记住我"ASP.NET MVC 中的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的登录表单中实现记住我"功能.我使用 ASP.NET MVC 作为我的 Web 应用程序.我设法让 cookie 的东西工作,但我未能自动登录用户,以防他/她之前选中了记住我复选框.我知道问题是什么,但我不知道如何解决它.

在我的 HomeController 中,我有以下内容:

private LoginViewModel CheckLoginCookie(){if (!string.IsNullOrEmpty(_appCookies.Email) && !string.IsNullOrEmpty(_appCookies.Password)){var login = 新的 LoginViewModel{电子邮件 = _appCookies.Email,密码 = _appCookies.Password};返回登录;}返回空;}公共 ActionResult 索引(){var login = CheckLoginCookie();如果(登录!= null)return RedirectToAction("登录", "用户", 登录);var viewModel = 新的 HomeIndexViewModel{介绍文字 =Lorem Ipsum 只是印刷和排版行业的虚拟文本.自 1500 年代以来,Lorem Ipsum 一直是行业标准的虚拟文本,当时一位不知名的印刷商拿着一个类型的厨房,并争先恐后地将其制作成一本类型的样本书.它幸存了下来不仅是五个世纪,还有电子排版的飞跃,基本保持不变.在 1960 年代,随着包含 Lorem Ipsum 段落的 Letraset 表格的发布,以及最近的桌面出版软件(如 Aldus PageMaker,包括 Lorem Ipsum 的版本)的发布,它得到了普及.",LastMinuteDeals = new List(),TrustedDeals = 新列表()};返回视图(视图模型);}

在我的 UserController 中,我有登录操作方法:

public ActionResult Login(){返回 PartialView(new LoginViewModel());}[HttpPost]公共操作结果登录(LoginViewModel dto){布尔标志 = 假;如果(模型状态.IsValid){如果(_userService.AuthenticateUser(dto.Email,dto.Password,false)){var user = _userService.GetUserByEmail(dto.Email);var uSession = 新用户会话{ID = user.Id,昵称 = 用户.昵称};SessionManager.RegisterSession(SessionKeys.User, uSession);标志 = 真;如果(dto.RememberMe){_appCookies.Email = dto.Email;_appCookies.Password = dto.Password;}}}如果(标志)return RedirectToAction("Index", "Home");别的{ViewData.Add("InvalidLogin", "您提供的登录信息不正确.");返回视图(dto);}}

所以基本上,我认为我会做的是从家庭控制器上的索引操作结果重定向用户,以防有登录cookie.但问题是 RedirectToAction 将触发 GET Login 操作方法,而不是负责登录用户的 POST.

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

解决方案

首先,您不应该将用户的凭据存储在 cookie 中.这是令人难以置信的不安全.密码将随每个请求一起传递,并以纯文本形式存储在用户计算机上.

其次,不要重新发明轮子,尤其是在涉及安全问题时,您永远不会做对.

ASP.Net 已经通过 Forms Authentication 和 Membership Providers 安全地提供了这个功能.你应该看看那个.创建默认 MVC 项目将包括基本身份验证设置.官方 MVC 站点有更多.>

更新

您仍然可以使用 .NET 表单身份验证,而无需实现成员资格提供程序.在基本层面上,它会像这样工作.

您在 web.config 中启用表单身份验证

<forms loginUrl="~/Account/Login" timeout="2880"/></认证>

您可以使用 [Authorize] 属性装饰要保护的操作或控制器.

[授权]公共视图结果索引(){//你的动作逻辑在这里}

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

[HttpPost]公共操作结果登录(LoginViewModel dto){//你的授权逻辑在这里如果(用户授权){//创建身份验证票var authTicket = new FormsAuthenticationTicket(1、userId,//用户id日期时间.现在,DateTime.Now.AddMinutes(20),//到期记住我,//真正记住"",//角色/");//加密票据并将其添加到cookie中HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket));Response.Cookies.Add(cookie);return RedirectToAction("索引");}}

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?

解决方案

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

  }

}

这篇关于实现“记住我"ASP.NET MVC 中的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆