13

私はこの質問と同じ問題を抱えているようです:Djangoログアウトの問題

私のは少し奇妙です、それはグーグルクロームで動作します....しかしFirefoxでは動作しません...

これは私のログアウト機能です:(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("/")

私が持っているsettings.pyで:

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

そして、アプリiamappsのurls.py(プロジェクトのURLに/ desktop /として含まれています):

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

詳細情報:

  • django 1.4.3(1.3から1.4に更新されました...)
  • Python 2.7
  • Chromeで動作しますが、Firefox 17.0.1、Linuxでは動作しません

それがグーグルクロームで機能するが、Firefoxでは機能しないという事実は私を最も困惑させます。Firefoxがユーザーをログオンしていることを記憶し続けることと関係があるようです...

編集: 私は壊れたパイプを手に入れました....しかし私はログアウト時にそれを手に入れていないようです...しかしログアウト後にホームビューに行きます....

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

編集2 ログアウトしてリダイレクトされた後、このビューに移動します。

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

このビューへのリクエストを使用したリダイレクトが問題の原因になると思います。ログには、まだユーザー'michel'が含まれていると思います(ビューはリダイレクトからのリクエストを使用し、ユーザーmichelが含まれているため)...ただし。 。ユーザーmichelはその間にログアウトされています...

編集3

提案のため、それはロガーによるものです。ロギングのコメントを外しても役に立ちませんそしてそれはデフォルトのロガーです:

import logging
logger = logging.getLogger(__name__)

編集4(30-12-2012)

私のログアウトは、ユーザーがログオンしている場合はログアウトリンクを表示し、ユーザーがログアウトしている場合はログインリンクを表示するメインウィンドウからです。また、ユーザーとグループのメンバーシップに応じてツールが入力されるツールバーも含まれています。

問題は、キャッシュとそのリクエストのユーザーがまだクリアされていないときに、このメインウィンドウをリロードしていることだと思います。どういうわけかChromeはこれを処理する方法を知っており、Firefoxはパイプの破損エラーを引き起こします。ブラウザで手動でキャッシュをクリアすると、リロード後に正しいビューになります。

解決策は、ユーザーを含むページに何も含まれていないページにリダイレクトするか、自分で適切なタイミングでキャッシュをクリアすることです。

この問題はおそらく同じことを説明しています...しかし、ユーザーがログアウトするためだけにブラウザで何かをすることは期待できませんか?GETを/login/にキャッシュするdjango1.4を参照してください

編集5(31-12-2012)

キャッシュの問題のようですが、これを修正する方法はまだわかりません。

これらは私のキャッシュ設定です:

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',
        }
    }

しかし、私はダミーキャッシュなしでも試しました

編集6(4-jan-2013)まだ解決策がありません....ログアウトの方法をdjangoの方法に変更し、現在信号を使用しています...以下の自分の回答を参照してください。

それでも、Firefoxがログアウトを停止する原因となる壊れたパイプエラーが発生します。キャッシュの問題ではありません。別のページに移動した場合、またはさらに悪いことに...管理ページに移動した場合。まだログオンしています。ログアウトする唯一の方法は、管理ページでログアウトすることです。管理者ユーザーでない場合は、Firefoxブラウザでログアウトする方法はありません。

管理インターフェースを使用してログオフすると、信号は正常に機能します...

信号をオフにして確認しましたが、Firefoxでのログアウトが機能しません。

結論:メインページ()に戻ると、問題が発生します。

編集7(2013年1月4日)テスト用に簡単なログアウトビューを作成しました。このテンプレートは次のとおりです。

<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>

およびログアウトビュー:

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

URLを次のように変更しました。

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'),

それでも、物事を簡単にするために...私は信号をオフにしました。

そしてそれはまだFirefoxで動作していません....しかしそれはクロムで動作します

Firefoxでは、ログアウトしたページには移動しません

4

5 に答える 5

13

私は通常、投稿されたビューを使用してユーザーをログアウトします。urls.pyこれをルートファイルに追加するだけです。

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

そして、あなたは行ってもいいでしょう。

幸せなDjangoing。

于 2012-12-25T17:03:13.213 に答える
3

最後に、私は完全にdjangoのデフォルトにほぼ戻りました...使用:

views.pyで:

from django.contrib.auth.forms import AuthenticationForm
from django.views.generic.edit import FormView

class LoginView(FormView):
    """
    This is a class based version of django.contrib.auth.views.login.


    """
    form_class = AuthenticationForm
    redirect_field_name = REDIRECT_FIELD_NAME
    template_name = 'iamapps/login.html'


    @method_decorator(csrf_protect)
    @method_decorator(never_cache)
    def dispatch(self, *args, **kwargs):
        return super(LoginView, self).dispatch(*args, **kwargs)

    def form_valid(self, form):
        """
        The user has provided valid credentials (this was checked in AuthenticationForm.is_valid()). So now we
        can check the test cookie stuff and log him in.
        """
        self.check_and_delete_test_cookie()
        login(self.request, form.get_user())
        return super(LoginView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(LoginView, self).get_context_data(**kwargs)
        apps_settings=iamapps_settings()
        if apps_settings[LOGON_BASE_APP_NAME]:
            self.extend_template="%s/base.html" % apps_settings[LOGON_BASE_APP_NAME]
        else:
            self.extend_template="iamapps/base.html"
        context['extend_template']=self.extend_template
        return context    

    def form_invalid(self, form):
        """
        The user has provided invalid credentials (this was checked in AuthenticationForm.is_valid()). So now we
        set the test cookie again and re-render the form with errors.
        """
        self.set_test_cookie()
        return super(LoginView, self).form_invalid(form)

    def get_success_url(self):
        if self.success_url:
            redirect_to = self.success_url
        else:
            redirect_to = self.request.REQUEST.get(self.redirect_field_name, '')

        netloc = urlparse.urlparse(redirect_to)[1]
        if not redirect_to:
            redirect_to = settings.LOGIN_REDIRECT_URL
        # Security check -- don't allow redirection to a different host.
        elif netloc and netloc != self.request.get_host():
            redirect_to = settings.LOGIN_REDIRECT_URL
        return redirect_to

    def set_test_cookie(self):
        self.request.session.set_test_cookie()

    def check_and_delete_test_cookie(self):
        if self.request.session.test_cookie_worked():
            self.request.session.delete_test_cookie()
            return True
        return False

    def get(self, request, *args, **kwargs):
        """
        Same as django.views.generic.edit.ProcessFormView.get(), but adds test cookie stuff
        """
        self.set_test_cookie()
        return super(LoginView, self).get(request, *args, **kwargs)

およびURL:

url(r'^login/$', LoginView.as_view(), name='login'),

これは私のすべての問題を解決しました...logginとlogioffonについて...

ログインとログアウトのシグナルは正常に機能しています。

from django.contrib.auth.signals import user_logged_out, user_logged_in

# Note, these login and logout signals are registered in imamstats views
def iam_logged_out_actions(sender, user, request, **kwargs):
    try:
        # ... do my logging out actiosn (stats etc.)
    except Exception, e:
        logger.error("Logging logout action error: %s" % e)

# Note, these login and logout signals are registered in imamstats views
def iam_logged_in_actions(sender, user, request, **kwargs):
    try:
        # ... do my log in stats etc. things
    except Exception, e:
        logger.error("Logging login action error: %s" % e)
于 2014-02-12T08:32:40.460 に答える
2

stackoverflowを参照しています...(別の検索を行いました)

私はこれを見つけました:.... Djangoのdjango.contrib.auth.logoutを参照してください..

しかし、それはさらに悪いことです....私はこれを見つけました...驚いた...しかしそれをすべて説明します: Django、Logout_URLはうまくリダイレ​​クトされません

私はそれがクリスマスイブに呪うことを許されていないバグ(@ ## $ %%)を修正しないことを知りました...。

したがって、カスタム作業を行うための解決策は、独自のビューを使用するのではなく、シグナルにあります。デフォルトのビューとリダイレクトを実行します...そしてこのドキュメントを使用してシグナルを作成します。https://docs.djangoproject.com/en/dev/topics/auth/#login-and-logout-signals

シグナルの追加は非常に簡単です。メインアプリ(iamapps)からmodels.pyに入れます。

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)

これは機能します....ただし、ログアウト時に失敗する可能性があると思われる壊れたパイプは解決されません...したがって、Firefoxでのログアウトは引き続き失敗します...そしてChromeでは機能します...djangoからログアウトします管理ページはFirefoxで動作します。シグナルには別の利点があります。管理インターフェイスでログアウトすると、シグナルが呼び出されます...

ログアウトするには、このurls.pyを使用します。

    url(r'^logout/$', 'django.contrib.auth.views.logout',  {'next_page': '/'}, name='iamapps.logout'),
于 2012-12-25T19:45:48.313 に答える
1

私の疑惑は、元のログアウトビューが、Cookieなどをクリアする応答を返し、その応答を破棄していることです。このように、単にユーザーに応答を返すようにしてみてください。

def my_logout(request):
    # something...
    return logout(request)
于 2012-12-25T23:49:12.893 に答える
1

検証された回答は、言及されたバージョンではうまく機能しますが、django2.2バージョンでは機能しなくなりました。したがって、ログアウト後にリダイレクトを正常に実行するには、属性を定義する必要があります。

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')),
]

これは、next_page属性をクラスLogoutViewに渡したことがわかります。この属性は、ログアウトが成功した後にリダイレクトまたは移動する場所を示します。これが誰かを助けるかもしれないことを願っています。ハッピーコーディング!

于 2019-07-29T07:53:13.817 に答える