Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django logout not working

Tags:

django

logout

I seem to have the same problem as in this question: Django logout problem

Mine is a bit weirder, it works in google chrome.... but not in firefox...

this is my logout function: (in views.py)

def my_logout(request):
    logger.debug("Logout called by user")
    try:
        # Here I do some custom stuff, like logging this action in a database and so on
        # For this question it shouldn't matter... because in a try catch
        # so whatever goes wrong here, logging out should work anyway
    except Exception, e:
        logger.info("Logging logout action error: %s" % e)
    logout(request)
    return HttpResponseRedirect("/")

in settings.py I have:

LOGIN_URL = '/desktop/login/'
LOGOUT_URL = '/desktop/logout/'
LOGIN_REDIRECT_URL = '/'

And in the urls.py of the app iamapps (include in the project urls as /desktop/):

url(r'^login/$', 'iamapps.views.my_login', name='iamapps.login'),
url(r'^logout/$', 'iamapps.views.my_logout', name='iamapps.logout'),

further info:

  • django 1.4.3 (just updated from 1.3 to 1.4 ....)
  • python 2.7
  • works in Chrome but not in Firefox 17.0.1, Linux

The fact that it does work in google chrome but does not work in firefox puzzles me the most. Seems it has something to do with firefox keeps remembering the user as being logged on...

EDIT: I get a broken pipe.... but I seem to get it not on logging out... but going to the home view after logout....

Traceback (most recent call last):
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 86, in run
    self.finish_response()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 127, in finish_response
    self.write(data)
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 210, in write
    self.send_headers()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 268, in send_headers
    self.send_preamble()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 192, in send_preamble
    'Date: %s\r\n' % format_date_time(time.time())
  File "/usr/lib/python2.7/socket.py", line 324, in write
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 58684)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 582, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/media/storage/django/sites/iamfloraservice/parts/django/django/core/servers/basehttp.py", line 139, in __init__
    super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  File "/usr/lib/python2.7/SocketServer.py", line 641, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 694, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------
[24/Dec/2012 14:33:25] "GET / HTTP/1.1" 200 48247

Edit 2 it goes to this view after loging out and being redirected:

def home(request, template='iamfloraservice/home.html'):

    logger.debug("Home view called by user %s" % request.user)
    return render_to_response(template,{},context_instance=RequestContext(request))

I think the redirect with the request to this view causes the problem.... In the log sais it's still user 'michel' (beacuse the view uses the request from the redirect, and that had user michel)... however... user michel is being logged out in the mean time....

EDIT 3

because of the suggestion it's due to the logger. unremarking the logging does not help And it's the default logger:

import logging
logger = logging.getLogger(__name__)

EDIT 4 (30-12-2012)

My logout is from a main window where I show a logout link when a user is logged on and a login link if a user is logged out. Also it contains a toolbar, which tools are filled depending on the the user and it's membership of groups.

I think the problem is, it's reloading this main window while the cache and the user in it's request isn't cleared yet. Somehow Chrome knows how to handle this, and firefox results in a broken pipe error. Clearing the cache manually in the browser results in the correct view after reload....

a solution might be to redirect to a page without anything in it that contains users... or find out to clear the cache on the right moment myselve....

this problem describes maybe the same... but I cannot expect users to do anything in the browser just to logout? see django 1.4 caching GET to /login/

Edit 5 (31-12-2012)

It seems it's a caching problem.... but not sure how to fix this yet.

these are my caching settings:

if not DEBUG:
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }
else:
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
        }
    }

But I tried without the dummycache as well

EDIT 6 (4-jan-2013) Still no solution.... I changed the way I log out to the django way, and I Am using the signals now... see my own answer below.

but still it gives the brokenpipe error which causes firefox stopping logging out. It's not a caching problem. If I go to another page, or even worse... the admin pages. I Am still logged on. The only way to logout is through the logout on the admin page.... If it's not an admin user... there is no way to get me logged out on the firefox browser.

When logging off using the admin interface, so the signal works fine...

I checked by turning off the signal.... and still the logging out in firefox does not work.

Conclusion: going back to the main page () is causing the problem.

EDIT 7 (4 jan 2013) I made a simple loggedout view for testing, this template:

<html>
<head>
<title>
Logged out
</title>
</head>
<body>
You are succesfully logged out.<br>
<br>
<a href="/">Go back to the main page</a>
or<br>
<a href="/desktop/login/?next=/">log in again</a>
</body>
</html>

and the logged out view:

class LoggedOutView(TemplateView):
    template_name = "iamapps/logged_out.html"

and changed the urls in to:

url(r'^logout/$', 'django.contrib.auth.views.logout',  {'next_page': '/desktop/loggedout/'}, name='iamapps.logout'),
#url(r'^logout/$', 'django.contrib.auth.views.logout_then_login',  name='iamapps.logout'),
url(r'^loggedout/$', LoggedOutView.as_view(),name='iamapps.loggedout'),

and still, to simplyfy things... I have the signals turned off.

and it's still not working in firefox.... but it works in chrome

In firefox it does not go to the logged out page

like image 897
michel.iamit Avatar asked Dec 24 '12 13:12

michel.iamit


4 Answers

I generally just use the contributed view to logout users. Simply add this to your root urls.py file:

# Would be nice to use settings.LOGIN_URL for `next_page` here, too
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/login'}),

and you'll be good to go.

Happy Djangoing.

like image 168
Craig Labenz Avatar answered Nov 17 '22 19:11

Craig Labenz


The verified answer work well for the mentioned version but it is not working in django 2.2 version any more. so in order to do successful redirect after logout you have to define the attributes.

from django.contrib import admin
from django.urls import path, include
from dark_bot import views
from django.contrib.auth import views as v
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index, name="index"),
    path('contact/', views.contact, name="contact"),
    path('search/', include('search.urls')),
    path('user/', include('accounts.urls')),
    path('dashboard/', include('dashboard.urls')),
    path('accounts/login/', v.LoginView.as_view(), name="login"),
    path('accounts/logout/',v.LogoutView.as_view(next_page='/'),name="logout")
    # path('dashboard/', include('dashboard.urls')),
]

This is how you can see I passed the next_page attribute to the class LogoutView which will tell where to redirect or go after successfull logout. Hope this may help someone. Happy Coding!

like image 31
Daud Ahmed Avatar answered Sep 20 '22 04:09

Daud Ahmed


browsing to stackoverflow... (did another search)

I found this one: .... see django.contrib.auth.logout in Django ..

But is is even worse.... I found this... astonished... but explains it all: Django, Logout_URL doesn't redirect well

The I found out it's a won't fix bug (@##$%%) not allowed to curse on christmas eve....

So the solution to do my custom stuff is in the signals in stead of using my own view. Do the default view and redirect... and use this documentation to create a signal.. https://docs.djangoproject.com/en/dev/topics/auth/#login-and-logout-signals

Adding the signals is quite easy, i put it in models.py off my main app (iamapps):

import logging
from django.contrib.auth.signals import user_logged_out
from django.contrib.auth.signals import user_logged_in
logger = logging.getLogger(__name__)

def iam_logged_out_actions(sender, user, request, **kwargs):
    #whatever...
    logger.debug("Logging out: user = %s" % user)

user_logged_out.connect(iam_logged_out_actions)

def iam_logged_in_actions(sender, user, request, **kwargs):
    #whatever...
    logger.debug("Logging in: user = %s" % user)

user_logged_in.connect(iam_logged_in_actions)

This works....however it does not solve the broken pipe which I think might cause the failure on the logging out... so logging out in firefox still fails... and in chrome it works... Logging out from django admin page works in firefox.. and the signal has another pro: also from logging out in the admin interface, the signal is being called...

for logging out i use now this urls.py:

    url(r'^logout/$', 'django.contrib.auth.views.logout',  {'next_page': '/'}, name='iamapps.logout'),
like image 3
michel.iamit Avatar answered Nov 17 '22 19:11

michel.iamit


My suspicion is that the original logout view returns a response that clears cookie or something like that, and you're throwing that response out. Could you try simply returning its response to the user, like this?

def my_logout(request):
    # something...
    return logout(request)
like image 1
che Avatar answered Nov 17 '22 19:11

che