【问题标题】:asp.net mvc 3 - set global user dataasp.net mvc 3 - 设置全局用户数据
【发布时间】:2011-05-08 01:54:08
【问题描述】:

如何通过页面设置保留姓名、姓氏等信息的全局用户数据?如果我使用会话变量,它会在 auth cookie 之前过期

谢谢!

【问题讨论】:

  • 您希望它持续多久?跨会话?
  • 是的,在身份验证会话中,我确实使用了“会话”变量,但提前到期
  • 您需要将其存储到数据库或其他形式的持久存储中。
  • 好的,但是如何在所有控制器上获取数据库信息,而不必在每个控制器上编写代码?
  • 重构您的代码,以便只有一个(或少数)控制器需要访问此信息并使用类似RenderPartial 的方法使其显示在所有页面上。

标签: session authentication asp.net-mvc-3 user-data


【解决方案1】:

您可以利用身份验证 cookie 中的 userdata 字段存储身份验证会话期间的数据。

以下代码是默认 MVC 项目中 AccountController 的 LogOn 操作:

 [HttpPost]
 public ActionResult LogOn(LogOnModel model, string returnUrl)
 {
    if (ModelState.IsValid)
    {
        if (Membership.ValidateUser(model.UserName, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
            if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
        }
    }
    // If we got this far, something failed, redisplay form
    return View(model);
}

你可以替换:

FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

与:

string fullName = "User full name";

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, model.Email, DateTime.Now,
                DateTime.Now.AddDays(2), model.RememberMe, fullName);

string encTicket = FormsAuthentication.Encrypt(ticket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = DateTime.Now.AddDays(2) });

如果你想存储比普通字符串更多的数据,你将不得不研究某种数据序列化器。

然后,当使用 auth cookie 时,您将不得不实现一些东西来解析序列化数据。

数据可通过以下方式获得:

((FormsIdentity)User.Identity).Ticket.UserData;

希望有帮助

编辑: 还将 DateTime.Now.AddDays(2) 更改为您希望身份验证会话保持有效的任何内容。

【讨论】:

  • 它并不“糟糕”,但在客户端存储数据已被证明不是最佳解决方案——尤其是在最近的 POET 漏洞之后。
【解决方案2】:

会话状态可能是configured,可以通过多种方式解决上述问题。具体来说,如果使用进程内会话状态(其中状态与正在运行的应用程序在同一应用程序域/池中维护),只需将超时时间增加到等于或大于表单 cookie 超时时间。如果您希望将会话存储在进程外(在远程系统或数据库中),请进行相应配置。
以下是一些资源:

【讨论】:

  • 谢谢,我喜欢这种方法,但不知道为什么我不能让它工作,我用 配置 web.conf .... 但我的会话变量仍在过期跨度>
  • 您是否对可能导致其回收的应用程序池进行了任何更改?此外,某些其他活动会导致应用程序池回收(即修改 web.config、重建应用程序、修改站点下的文件超过 5(?)次)。
  • 啊,我正在开发项目,所以重建和发布是经常性的工作!谢谢!!!!
【解决方案3】:

将其存储在您的身份验证 cookie 中可能会被伪造,也可能会过期。 怎么样 - 如果你可以让你的 session 和 auth cookie 同时过期,那会有效吗?如果是这样,我可以轻松地为您提供该解决方案。 下面的代码检查会话是否不可用,如果是,您将被重定向到登录页面。 将下面的 login.aspx 更改为您的登录名。同样在登录时,您必须将 Session["UniqueUserId"] 设置为某个值(可以是任何值.. 只需设置为某个值)

protected void Application_PreRequestHandlerExecute(对象发送者,EventArgs e) { //只有在可用时才访问会话状态 if (Context.Handler 是 IRequiresSessionState || Context.Handler 是 IReadOnlySessionState) { //如果我们通过了身份验证并且我们在这里没有会话.. 重定向到登录页面。 HttpCookie authenticationCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (authenticationCookie != null) { FormsAuthenticationTicket authenticationTicket = FormsAuthentication.Decrypt(authenticationCookie.Value); if (!authenticationTicket.Expired) { if (Session["UniqueUserId"] == null) { //这意味着由于某种原因会话在身份验证票证之前过期。强制登录。 FormsAuthentication.SignOut(); Response.Redirect("Login.aspx", true); 返回; } } } } }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多