在ASP.NET中,何时应该使用Session.Clear()而不是Session.Abandon()?

122

Session.Clear() 和 Session.Abandon() 都能清除会话变量。据我所知,Abandon() 结束当前会话,并创建一个新的会话,因此触发了 End 和 Start 事件。

在大多数情况下,如注销用户,调用 Abandon() 更可取。是否存在 Clear() 更合适的场景?性能上是否有很大差异?

4个回答

178

Session.Abandon()销毁session并触发Session_OnEnd事件

Session.Clear()删除对象中的所有值(内容)。具有相同键的session仍然存在。

因此,如果使用Session.Abandon(),则会丢失该特定会话,并且用户将获得新的会话密钥。例如,当用户注销时可以使用它。

如果您想要用户保持在同一个session中(例如,如果您不想让用户重新登录),并重置所有与session相关的数据,请使用Session.Clear()


1
我认为最好使用RemoveAll(),正如“Darin Dimitrov”在这里建议的那样:https://dev59.com/XG865IYBdhLWcg3wNLw7#3931344。 - Bibhu
6
他是如何建议使用RemoveAll() 而非 Clear() 的呢?在他的答案中,我看到的是RemoveAll() 调用了Clear(),并且似乎在功能上是相同的。 - Adam Miller
1
只需在使用Windows身份验证的内部应用程序中使用Session.Abandon()作为“注销”即可(Chrome,FF),但用户无需重新进行身份验证,但会话已处理并发出新会话,这符合我的要求。 - brichins

14

仅在用户注销时使用Session.Clear()可能存在安全漏洞。因为就Web服务器而言,会话仍然有效。因此,嗅探并获取会话ID,并劫持该会话是相当容易的。

出于这个原因,在注销用户时,更安全和明智的做法是使用Session.Abandon()来销毁会话并创建一个新会话(即使注销UI页面是新会话的一部分,新会话也不会包含任何用户详细信息,劫持新会话将等同于拥有一个新的会话,因此它将是无效的)。


4
劫持一个空的会话有什么意义呢?劫持者仍然需要登录,而且没有数据可以不小心地提供给新用户。 - Trisped
我认为这就是关键。只有在调用放弃操作时,它才是空的。否则,劫持的会话中可能存在数据(尽管已经注销)。 - James Hurley

3

Session.Abandon 会销毁会话,因此在注销时应使用它。如果要清空电子商务网站上的购物篮,则可以考虑使用 Session.Clear


但是如果我使用 Session.Abandon 来清除特定的购物篮呢? - WTFZane

0

我遇到了这个问题,尝试了两种方法,但最终只能删除像“pageEditState”这样的垃圾,而不删除用户信息,以免再次查找。

public static void RemoveEverythingButUserInfo()
{
    foreach (String o in HttpContext.Current.Session.Keys)
    {
        if (o != "UserInfoIDontWantToAskForAgain")
            keys.Add(o);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接