tao_oat
tao_oat

Reputation: 1037

Django does not delete cookie

I have a site running Django 1.6 using a custom authentication backend (CoSign). Authentication works, but to log out I need to delete a cookie.

This is the cookie before logging out, using Firebug:

Here is my logout view:

from django.contrib.auth.views import logout as django_logout

def logout(request):
    if request.user.is_authenticated():
        response = django_logout(
                       request,
                       next_page=reverse("logout-confirmation")
                   )
        response.delete_cookie(
            'cookie_name',
            domain="cookie_domain"
        )
        return response
    else:
        messages.add_message(
            request,
            messages.ERROR,
            "You can't log out if you aren't logged "
            "in first!"
        )
        return HttpResponseRedirect(reverse("frontpage"))

cookie_name and cookie_domain in my code match the actual name and domain of the cookie.

Here are the response headers of the logout view:

Connection: "close"
Content-Length: "0"
Set-Cookie: "{{ cookie_name }}=; Domain={{ cookie_domain }}; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/sessionid=25lysb3tzhozv464mrgg08uqz100ur39; expires=Mon, 15-Sep-2014 19:07:22 GMT; httponly; Max-Age=1209600; Path=/"
Vary: "Cookie"

After going to my logout view, however, the cookie still exists! Can anyone shed some light on why this happens?

Upvotes: 9

Views: 8279

Answers (4)

I couldn't delete the cookies set by response.cookies[] while I could delete the cookies set by response.set_cookie() as shown below. *You can see my question and my answer explaining the difference between response.set_cookie() and response.cookies[]:

# "my_app1/views.py"

from django.http import HttpResponse

def test(request):
    response = HttpResponse('Test')
    response.set_cookie('first_name', 'John') # Here
    response.cookies['last_name'] = 'Smith' # Here
    return response
# "my_app1/views.py"

from django.http import HttpResponse

def test(request):
    response = HttpResponse('Test')
    response.delete_cookie('first_name') # Deleted
    response.delete_cookie('last_name') # Undeleted
    return response

Upvotes: 0

AJNinja
AJNinja

Reputation: 140

You can get around this problem by expiring the cookie like this:

response = django_logout(request,
                             next_page=reverse("logout-confirmation"))

response.set_cookie('cookie_name', domain="cookie_domain", max_age_seconds=1)

return response

The code above will expire your cookie after one second. This will ensure that before response reaches browser, 'cookie_name' would have expired.

Upvotes: 1

tao_oat
tao_oat

Reputation: 1037

I fixed this by using set_cookie() with a manually entered expiry date, rather than delete_cookie(). Additionally, if I set the domain in Django, it prefixed a period which meant that it didn't match the existing cookie. I didn't enter a domain and it used the default, which worked.

Upvotes: 5

Mikko Ohtamaa
Mikko Ohtamaa

Reputation: 83666

You are not returning response you construct for deleting cookie. Instead, you are returning new HttpResponseRedirect object. This is the response being served to the browser.

Do not return HttpResponseRedirect, but return response created with django_logout().

Upvotes: 0

Related Questions