Cookie 未删除
Posted
技术标签:
【中文标题】Cookie 未删除【英文标题】:Cookie is not deleted 【发布时间】:2010-12-18 18:35:49 【问题描述】:我正在使用以下代码在我的 asp.net mvc(C#) 应用程序中设置 cookie:
public static void SetValue(string key, string value, DateTime expires)
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
HttpCookie cookie = new HttpCookie(key, value) Expires = expires ;
_response.Cookies.Set(cookie);
当用户单击注销时,我需要删除 cookie。设置的 cookie 没有通过 Clear/Remove 删除/删除。代码如下:
public static void Clear()
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
_request.Cookies.Clear();
_response.Cookies.Clear();
public static void Remove(string key)
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
if (_request.Cookies[key] != null)
_request.Cookies.Remove(key);
if (_response.Cookies[key] != null)
_response.Cookies.Remove(key);
上述两个功能我都试过了,但是当我尝试检查是否存在时,cookie仍然存在。
public static bool Exists(string key)
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
return _request.Cookies[key] != null;
这里可能有什么问题?或者我需要做什么来删除/删除 cookie?
【问题讨论】:
【参考方案1】:Response.Cookies["key"].Expires= DateTime.Now;
【讨论】:
这比Rippo 10.5 年前的答案好吗?如果有,请详细说明。【参考方案2】:在玩了一段时间并在这里尝试了所有其他答案之后,我发现这里没有一个答案是完全正确的。
正确的部分是您必须发送过期的 cookie 才能进行删除。没有人知道的部分(但在 Ed DeGagne 发布的 Microsoft 代码中得到了证明)是用于删除的 cookie 选项必须与最初用于设置 cookie 的 cookie 选项完全匹配。
例如,如果您最初使用 HttpOnly 选项创建 cookie,那么您在删除 cookie 时也必须设置此选项。我预计确切的行为会因浏览器而异,并且可能会随着时间的推移而变化,因此唯一可以长期使用的安全选项是确保删除响应中的所有 cookie 选项与最初用于创建 cookie 的 cookie 选项完全匹配.
【讨论】:
赞成。再补充一点,所有这些选项必须在旧 cookie 和新的空 cookie 之间匹配,以便浏览器实际删除它:域、路径、HttpOnly、安全。【参考方案3】:实现这一点的最佳方法是使用 Reflector 之类的工具,并查看 System.Web.Security.FormsAuthentication.SignOut 方法如何实现删除身份验证 cookie。
在 Reflector 中,打开 System.Web 并导航到 FormsAuthentication 对象并找到 SignOut 方法。右键单击它并选择“反汇编”(从菜单中选择您的语言)。
VB.NET
Public Shared Sub SignOut()
FormsAuthentication.Initialize
Dim current As HttpContext = HttpContext.Current
Dim flag As Boolean = current.CookielessHelper.DoesCookieValueExistInOriginal("F"c)
current.CookielessHelper.SetCookieValue("F"c, Nothing)
If (Not CookielessHelperClass.UseCookieless(current, False, FormsAuthentication.CookieMode) OrElse current.Request.Browser.Cookies) Then
Dim str As String = String.Empty
If (current.Request.Browser.Item("supportsEmptyStringInCookieValue") = "false") Then
str = "NoCookie"
End If
Dim cookie As New HttpCookie(FormsAuthentication.FormsCookieName, str)
cookie.HttpOnly = True
cookie.Path = FormsAuthentication._FormsCookiePath
cookie.Expires = New DateTime(&H7CF, 10, 12)
cookie.Secure = FormsAuthentication._RequireSSL
If (Not FormsAuthentication._CookieDomain Is Nothing) Then
cookie.Domain = FormsAuthentication._CookieDomain
End If
current.Response.Cookies.RemoveCookie(FormsAuthentication.FormsCookieName)
current.Response.Cookies.Add(cookie)
End If
If flag Then
current.Response.Redirect(FormsAuthentication.GetLoginPage(Nothing), False)
End If
End Sub
以上面为例,我可以在共享程序集中创建一个名为 RemoveCookie() 的通用方法,代码如下:
VB.NET
''' <summary>
''' Method to remove a cookie
''' </summary>
''' <param name="key">Key</param>
''' <remarks></remarks>
Public Shared Sub RemoveCookie(ByVal key As String)
' Encode key for retrieval and remove cookie
With HttpContext.Current
Dim cookie As New HttpCookie(.Server.UrlEncode(key))
If Not IsNothing(cookie) Then
With cookie
.HttpOnly = True
.Expires = New DateTime(&H7CF, 10, 12)
End With
' Remove from server (has no effect on client)
.Response.Cookies.Remove(.Server.UrlEncode(key))
' Add expired cookie to client, effectively removing it
.Response.Cookies.Add(cookie)
End If
End With
End Sub
使用 FireBug 和 FireBug 的 Cookie 插件(在 FireFox 中)对此进行了测试后,我可以证明 cookie 会立即被删除。
有任何问题,欢迎私信我。
【讨论】:
顺便说一句,如果你没有对你的键和值进行 UrlEncoding(你应该是),那么只需删除 .Server.UrlEncode(key) 并替换为 key。 代码很多,解释不多。本来可以更好地回答这个问题的。【参考方案4】:只是为了添加其他内容,我还将值作为 null 传回,例如
public static void RemoveCookie(string cookieName)
if (HttpContext.Current.Response.Cookies[cookieName] != null)
HttpContext.Current.Response.Cookies[cookieName].Value = null;
HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Now.AddMonths(-1);
【讨论】:
谢谢,这就是我们所需要的一切【参考方案5】:Request 和 Response 对象中的 Cookies 集合不是浏览器中 cookie 的代理,它们是浏览器发送给您和您发回的一组 cookie。如果您从请求中删除 cookie,则它完全是服务器端的,并且如果您在响应中没有 cookie,则您不会将任何内容发送回客户端,这不会更改浏览器中的 cookie 集全部。
要删除 cookie,请确保它在响应 cookie 集合中,但过期时间已过。
【讨论】:
【参考方案6】:清除响应的 cookie 不会指示浏览器清除 cookie,它只是不会将 cookie 发送回浏览器。要指示浏览器清除 cookie,您需要告诉它 cookie 已过期,例如
public static void Clear(string key)
var httpContext = new HttpContextWrapper(HttpContext.Current);
_response = httpContext.Response;
HttpCookie cookie = new HttpCookie(key)
Expires = DateTime.Now.AddDays(-1) // or any other time in the past
;
_response.Cookies.Set(cookie);
【讨论】:
这还不够。看看我下面回复中的代码。 @Ed - 你的代码和我的完全一样,除了它有一些不必要的行,比如检查一个新实例化的对象是否存在(它确实存在)。您认为这缺少什么? 是的,空检查是不必要的。但我发现我需要两者:'从服务器中删除(对客户端没有影响).Response.Cookies.Remove(key)'在客户端过期.Response.Cookies.Add(cookie) 否则cookie实际上永远不会被删除。从微软的代码和我看到的其他示例来看,两者都做似乎是保证 cookie 确实被删除的方法。 你不想做 AddYears(-1) 以确保如果用户的时钟关闭,cookie 会过期吗? @GregBeech - 为什么我们需要这一行:“_response = httpContext.Response;”以上是关于Cookie 未删除的主要内容,如果未能解决你的问题,请参考以下文章
关闭会话时未删除移动浏览器(chrome、safari)cookie
CSRF cookie 未设置 - 可能被 kubernetes 入口阻止