ASP.NET MVC 记住我
Posted
技术标签:
【中文标题】ASP.NET MVC 记住我【英文标题】:ASP.NET MVC RememberMe 【发布时间】:2011-01-28 00:02:33 【问题描述】:在搜索了很多之后,我没有得到任何答案,最后我不得不回复你。下面我详细解释我的问题。太长了,请不要放弃阅读。我已经用简单的语言解释了我的问题。
我一直在开发一个 asp.net mvc 项目。 我正在使用标准的 ASP.NET 角色和成员资格。 一切正常,但记住我的功能根本不起作用。 我列出了所有工作细节。希望大家帮我解决这个问题。
我只需要这个:
我需要用户登录到 Web 应用程序。在登录期间,他们可以使用记住我或不使用它登录。 如果用户使用记住我登录,我希望浏览器能够长时间记住它们,比如说至少一年或相当长的时间。他们在 www.dotnetspider.com、www.codeproject.com、www.daniweb.com 和许多其他网站上的做法。 如果用户在不记得我的情况下登录,那么浏览器应该允许访问网站大约 20 -30 分钟,然后他们的会话应该过期。当用户登录并关闭浏览器而不退出时,他们的会话也应该过期。
注意:我通过为用户创建自己的 talbes 并针对我的数据库表进行身份验证,在我的其他项目中设置 cookie 和会话,成功地实现了上述功能,而无需使用标准的 asp.net 角色和成员资格。但是对于这个项目,我们从一开始就使用标准的 asp.net 角色和成员资格。我们认为它会起作用,并且在测试时构建了所有内容之后,它就不起作用了。现在我们不能用标准的 asp.net 角色和成员资格替换现有的功能,用我自己的自定义用户表和所有东西,你明白我在说什么。
要么存在标准 asp.net 角色和成员资格功能的某种错误,要么我对标准 asp.net 角色和成员资格的整个概念有错误。我已经在上面说明了我想要的。我觉得很简单也很合理。
我做了什么
-
带有用户名、密码和记住我字段的登录表单。
我在 web.config 中的设置:
在我的控制器操作中,我有这个:
FormsAuth.SignIn(userName, rememberMe);
public void SignIn(string userName, bool createPersistentCookie) FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
现在问题如下:
我已经在上面的部分中说过“我只需要这个”。 用户可以成功登录系统。他们的会话存在的时间与 web.config 中超时值中指定的时间一样多。我还提供了我的 web.config 示例。在我的示例中,如果我将超时设置为 5 分钟,那么用户会话将在 5 分钟后过期,没关系。但是如果用户关闭浏览器并重新打开浏览器,用户仍然可以在没有登录的情况下进入网站,直到“超时”中指定的时间没有过去。超时值的滑动到期也可以正常工作。现在,如果用户在选中记住我的情况下登录系统,用户会话在 5 分钟后仍会过期。这不是好的行为,是吗?我的意思是说,如果用户登录系统时勾选了记住我,他应该被记住很长时间,直到他没有退出系统或用户没有手动删除浏览器中的所有 cookie。如果用户在不记得我的情况下登录系统,他的会话应该在 web.config 中指定的超时时间值之后过期,并且如果用户关闭浏览器。问题是,如果用户关闭浏览器并重新打开它,他仍然可以在不登录的情况下进入网站。
我在网上搜索了很多关于这个主题的内容,但我找不到解决方案。在 Scott Gu 发表的关于完全相同主题的博文 (http://weblogs.asp.net/scottgu/archive/2005/11/08/430011.aspx) 中。用户在他们的 cmets 中抱怨同样的事情,但 Scott 先生没有给出简单的解决方案。
我在以下地方阅读过它: http://weblogs.asp.net/scottgu/archive/2005/11/08/430011.aspx http://geekswithblogs.net/vivek/archive/2006/09/14/91191.aspx
我想这是很多用户的问题。从 Scott Gu 先生的博文中可以看出。
您的帮助将不胜感激。 提前致谢。
【问题讨论】:
你是对的。你的问题太长了。你应该让它更短。 顺便说一句,我是 Scott Guthrie 先生,又名 The Gu。 一点也不长。不需要跳过循环来理解问题。 :) 【参考方案1】:我已经实现了同样的东西,当我测试它时,它在 Mozila 中运行良好,但在所有电脑的 IE8 中都无法运行,我还更新了设置以在 IE 中接受 cookie,但仍然无法运行。
Internet Explorer 8.x
-
点击工具菜单。
在菜单中选择 Internet 选项 - 将打开一个新窗口。
单击窗口顶部附近的“隐私”选项卡。
单击窗口的默认按钮。
移动滑块,使其位于中高以下的级别之一(包括中、低、接受所有 Cookie)。
单击“确定”保存更改。
您现在应该可以将商品添加到购物车了。
【讨论】:
【参考方案2】:您想要做的是在选中“记住我”选项时与未选中时设置不同的超时。不幸的是,SetAuthCookie 方法不允许您手动设置过期时间,因此您必须自己设置。
那么问题来了,该怎么做呢?
ASP.NET MVC 使用 System.Web.Security 的 FormsAuthentication 类来做到这一点,因为如果您还想支持配置设置和无 cookie 浏览和 SSL,这并非易事,但我认为如果您只是这样做:
int timeout = rememberMe ? 525600 : 30; // Timeout in minutes, 525600 = 365 days.
var ticket = new FormsAuthenticationTicket(userName, rememberMe, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = System.DateTime.Now.AddMinutes(timeout);// Not my line
cookie.HttpOnly = true; // cookie not available in javascript.
Response.Cookies.Add(cookie);
...您将获得所需的基本版本。
注意:我没有测试此代码。
【讨论】:
戴夫,您的解决方案对我有用。但仅仅这样做是不够的。我不得不添加一行代码让它记住至少一年。我已经写在下面了。 如果有人发现这不起作用,请确保该过程未使用登录控件的重定向 URL,您只需添加 Response.Redirect("./");到方法的末尾以防止默认行为(这是用 web.config 中的超时覆盖超时)【参考方案3】:只是一个关于在共享环境中使用会员身份验证票的简短说明,供可能遇到该问题的任何人使用。我有一个 mvc 站点在 godaddy 运行,但在记住我时遇到了麻烦。这是解决方案:
<system.web>
<machineKey
validationKey="4C6404A3B305CD6E8CFEAC258F042FB95E45E9C3C2CEC3AAB838996CFBE661E41DF1A1BAC75B9B45E02147612FD9B71CA74DDA50B0D0D6ED11F0BB8E31048953"
decryptionKey="BC471CF17A97B08A9DF85C7B502AD95680E3BE4418FD9C6CEA57E7F97ED64291"
validation="SHA1" decryption="AES"
/>
感谢: http://www.geekfreeq.com/aspnet-remember-me-option-forms-authentication-not-working/
【讨论】:
该链接现在显然已备份。 您也可以在这里创建这些设置aspnetresources.com/tools/machineKey【参考方案4】:凯文和戴夫,你们摇滚,伙计。
Dave,除了您的代码之外,我还必须再添加一行以使其正常工作。我的意思是让它记住至少一年。除了您的代码之外,我还必须为 cookie.Expires 赋值才能使其工作。如果此行 cookie.Expires 未设置,则 cookie 在计算机重新启动后丢失,我的意思是在会话结束时。我在 FireFox 中注意到了这一点。我浏览了 cookie 的详细信息,发现:如果未设置 cookie.Expires,则 Firefox 中“Expires:”属性的值为“在会话结束时”,但如果设置了 cookie.Expires,则“Expires”的值:" Firefox 中的属性是设置 cookie.Expires 值的日期时间。
代码如下:
int timeout = createPersistentCookie ? 525600 : 2; // Timeout in minutes,525600 = 365 days
var ticket = new FormsAuthenticationTicket(userName,createPersistentCookie,timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = System.DateTime.Now.AddMinutes(timeout);//My Line
HttpContext.Current.Response.Cookies.Add(cookie);
谢谢你们,这真是一个很棒的解决方案。
【讨论】:
【参考方案5】:这不是问题,这是一个功能:)
用户的会话还没有过期,所以即使他们关闭并重新打开浏览器,cookie 仍然是好的。
是 cookie 的过期导致用户会话无效。
【讨论】:
感谢 kervin,你是对的。这消除了我的一个疑虑。以上是关于ASP.NET MVC 记住我的主要内容,如果未能解决你的问题,请参考以下文章
如何在Asp.net Core的登录过程中为“记住我”设置单个cookie超时?