【问题标题】:Increase timeout of an already started session增加已启动会话的超时
【发布时间】:2014-03-26 02:43:06
【问题描述】:

我想在我的自定义登录控件中添加“保持登录”选项。

这是我当前使用会话的方式: 我正在手动保存和读取来自HttpContext.Current.Session["key"] 的值。工作正常。

web.config 的相关部分:

<sessionState mode="StateServer" useHostingIdentity="true" cookieless="false" timeout="120" stateConnectionString="tcpip=127.0.0.1:42424" />
<authentication mode="Forms">
  <forms loginUrl="/login" name="AuthCookie" timeout="120" slidingExpiration="true" path="/" />
</authentication>
<authorization>
 <allow users="*" />
</authorization>

如您所见,会话的默认持续时间为 120 分钟。

“退出”:

  Session.Clear();
  Session.Abandon();

通过带有文本框的自定义登录控件,我授予对成员区域的访问权限。 (我不使用System.Web.Security.FormsAuthentication
输入有效凭据并选中“保持登录”复选框后,我想将已经活动的会话的持续时间增加到约 30 天。

到目前为止,我已经找到了类似的解决方案

FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1, "username", DateTime.Now, DateTime.Now.AddMinutes(1), false, "username");
string encTicket = FormsAuthentication.Encrypt(fat);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = fat.Expiration });

这不起作用,因为 System.Web.Security.FormsAuthentication.Timeout 仍然是 120 分钟。 设置也是如此

Session.Timeout = 666;

有什么建议吗?

【问题讨论】:

    标签: c# asp.net session


    【解决方案1】:

    你不能这样处理它。您不能将会话持续数天 - 它不会很好地扩展。

    大多数人所做的是提供一种自动登录的方法,这样当他们的会话到期时,他们可以在下一次操作/重新加载时无缝地重新登录。大多数人使用包含唯一哈希的 cookie 来执行此操作,该哈希在服务器上进行检查。如果您希望此人登录 30 天,您只需将 cookie 设置为在 30 天后过期。

    【讨论】:

    • 感谢您的意见。我使用加密的 cookie 以这种方式实现它。
    • 很高兴听到它成功了!您是在 Forms Authentication 框架内完成的吗?如果是这样,我很乐意听到/查看详细信息。
    • 我添加了一些细节 ;)
    【解决方案2】:

    我决定简要总结一下我最终是如何做到的,因为@David Haney 要求我这样做:

    我在我的用户表中添加了一个列,其中包含一个用于“重新登录”/再次提供凭据的 GUID。该 GUID 在登录时创建并存储在数据库中。 它还作为加密值存储在 cookie 中。 (我的网站不使用 SSL)

    添加到登录例程(如果用户选中了“记住我”复选框):

    HttpCookie aCookie = new HttpCookie("Session");
    Guid sessionGuid =  // Buisiness layer call to generate value
    String sessionID = sessionGuid.ToString();
    aCookie.Value = Helper.Protect(sessionID, "sessionID");
    aCookie.Expires = DateTime.Now.AddDays(30);
    Response.Cookies.Add(aCookie);                    
    

    Helper.Protect 和 Helper.Unprotect 用于从此处How to use MachineKey.Protect for a cookie? 将加密和 MAC 签名值存储在 cookie 中。

    重新记录是通过让每个内容页面都继承自一个类来实现的,该类实现了该逻辑并继承自System.Web.UI.Page

    public class BasePage : System.Web.UI.Page
    {
     protected override void OnInit(EventArgs e)
     {
        base.OnInit(e);
    
       if (Request.Cookies["Session"] != null && !CustomIsLoggedInCheckMethod)
       {
         String unprotected = Helper.Unprotect(Request.Cookies["Session"].Value, "sessionID");
         Guid sessionID = Guid.Parse(unprotected);
        // Calls to buisiness layer to get the user, set sessions values et cetera
       }
     }
    }
    

    如果用户在上次会话后被禁止或注销,则 cookie 值到期日期将设置为过去的日期:

    HttpCookie myCookie = new HttpCookie("Session");
    myCookie.Expires = DateTime.Now.AddDays(-1d);
    Response.Cookies.Add(myCookie);
    

    编辑: 啊,我忘了提这个。我还添加了一个通知栏,告诉用户他已重新登录。它基于http://blog.grio.com/2012/11/a-copypaste-ble-jquery-notification-bar.html
    Demo

    【讨论】:

    • 不错,很好的方法。我有一件事要提。如果您曾经将您的应用程序扩展到一台服务器之外,您的 cookie 就会出现问题。因为您已经使用特定服务器 MAC 的签名对其进行了加密,所以循环中处理 cookie 的下一个服务器可能无法解密它。出于这个原因,我会考虑一个“共享秘密”模型,其中所有服务器都使用密钥通过 AES 加密/解密。干得好!
    • 感谢您的提及。昨天我看到另一个用户询问有关服务器场和保护/取消保护方法的问题,解决方案是强制服务器场中的每台服务器使用相同的 MachineKey。我想这会起作用,如果我的网站规模这么大 =)
    • 我忘了提到我添加了重新登录的视觉提及;)
    猜你喜欢
    • 2012-01-29
    • 1970-01-01
    • 2019-09-27
    • 2016-03-02
    • 2018-06-05
    • 1970-01-01
    • 2018-06-20
    • 2014-03-26
    • 1970-01-01
    相关资源
    最近更新 更多