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

创建未设置的 cookie 按钮

无法在 symfony 中删除 cookie

CSRF cookie 未设置 - 可能被 kubernetes 入口阻止

如何在与他人共享之前从 HAR 文件中删除 Cookie 值

JavaWeb期末复习(未完成)