2009-11-20 21 views
27

Sto usando il seguente codice per impostare un cookie nel mio asp.net mvc (C#) applicazione:Cookie non viene eliminato

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); 
} 

ho bisogno di cancellare i cookie quando l'utente fa clic logout. Il cookie impostato non rimuove/elimina con Cancella/Rimuovi. Il codice è il seguente:

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); 
    } 
} 

Ho provato entrambe le funzioni di cui sopra, ma ancora il cookie esiste quando si tenta di controllare esiste.

public static bool Exists(string key) 
{ 
    var httpContext = new HttpContextWrapper(HttpContext.Current); 
    _request = httpContext.Request; 
    _response = httpContext.Response; 
    return _request.Cookies[key] != null; 
} 

Quale può essere il problema qui? o qual è la cosa che devo fare per rimuovere/eliminare il cookie?

risposta

49

La cancellazione dei cookie della risposta non indica al browser di cancellare il cookie, ma semplicemente non reinvia i cookie al browser. Per istruire il browser a cancellare il cookie è necessario comunicargli che il cookie è scaduto, ad es.

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); 
} 
+0

Questo non è abbastanza. Dai un'occhiata al codice nella mia risposta qui sotto. –

+1

@Ed - Il tuo codice fa esattamente lo stesso mio, a parte il fatto che ha un paio di righe non necessarie come il controllo della presenza di un oggetto appena istanziato (lo fa).Cosa pensi che questo manchi? –

+0

Sì, il controllo null non è necessario. Ma ho trovato avevo bisogno di a entrambi: 'Rimuovi dal server (non influisce sul client) .Response.Cookies.Remove (chiave) ' scadono il client .Response.Cookies.Add (cookie) Altrimenti il cookie non viene mai effettivamente cancellato. A giudicare dal codice Microsoft e da altri esempi che ho visto, fare entrambi sembra essere il modo per garantire che il cookie venga effettivamente rimosso. –

4

La collezione cookie nella richiesta e la risposta gli oggetti non sono proxy per i cookie nel browser, sono un insieme di ciò che i cookie del browser invia e rispedite. Se rimuovi un cookie dalla richiesta è interamente lato server, e se non hai i cookie nella risposta, non invierai nulla al client, che non cambierà il set di cookie nel browser a tutti.

Per eliminare un cookie, assicurarsi che sia nella serie di cookie di risposta, ma che abbia una scadenza nel passato.

4

Solo per aggiungere qualcos'altro, restituisco il valore come null, ad es.

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); 
     } 
    } 
+1

Grazie, questo è davvero tutto ciò che è necessario – spojam

3

Il modo migliore per implementare questo è quello di utilizzare uno strumento come riflettore e vedere come il metodo System.Web.Security.FormsAuthentication.SignOut implementa rimuovere il cookie di autenticazione.

In Reflector, aprire System.Web e accedere all'oggetto FormsAuthentication e trovare il metodo SignOut. Fai clic destro su di esso e seleziona "Disassembla" (scegli la lingua dal menu).

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 

Con quanto sopra come esempio, sono stato in grado di creare un metodo comune denominato RemoveCookie() in un assembly condiviso, il codice è qui sotto:

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 

Dopo aver testato questo utilizzando Firebug e il cookie add-in per FireBug (in FireFox), posso attestare che il cookie viene immediatamente rimosso.

Qualsiasi domanda, sentitevi liberi di mandarmi messaggi.

+0

BTW, se non si UrlEncodifica la chiave e il valore (si dovrebbe essere), quindi basta rimuovere .Server.UrlEncode (chiave) e basta sostituire con la chiave. –

+0

Un sacco di codice e non molte spiegazioni. Avrebbe potuto rispondere meglio alla domanda. –

+1

In realtà è auto-esplicativo in realtà .... –

Problemi correlati