【问题标题】:How to logout from Django with custom user model and custom logout view?如何使用自定义用户模型和自定义注销视图从 Django 注销?
【发布时间】:2019-08-30 01:40:06
【问题描述】:

我制作了一个应用程序并扩展了AbstractUser 以将一些字段添加到我的User 模型中。之后,一切都按预期工作(登录,创建用户,重置密码......)但是当我尝试使用默认注销时 django.contrib.auth.LogoutViewinclude('django.contrib.auth.urls') 它只会忽略注销。当我返回受限页面时,我可以进入并查看内容,并且我的用户实际上已登录!

我创建了一个这样的自定义注销视图

def custom_logout(request):
    print('Loggin out {}'.format(request.user))
    auth.logout(request)
    print(request.user)
    return HttpResponseRedirect('/restrictedpage')

在受限页面上,我有一个打印语句向用户展示

print("User logged: {}".format(request.user))

当我单击注销时,控制台中会显示以下内容:

"GET /restrictedpage  HTTP/1.1" 200 19820
User logged: ceterre
 ----- This is where i click logout ------
Loggin out AnonymousUser
AnonymousUser
"GET /accounts/logout/ HTTP/1.1" 302 0  ----- this redirects me to /restrictedpage
User logged: ceterre
"GET /restrictedpage HTTP/1.1" 200 19820

这个字面意思是:

 - I know ceterre is logged
 - logging out ceterre
 - user logged: AnonymousUser
 - redirect to restricted page (where I should have no access since im supposedly logged out)
 - user logged: ceterre (without any login or anything...)

【问题讨论】:

    标签: python django django-authentication


    【解决方案1】:

    Django 3+:使用自定义的基于类的视图

    模板视图

    为避免与django.contrib.auth 及其默认值发生冲突,请创建一个具有唯一名称的新视图。使用内置函数django.contrib.auth.logout 实际注销用户。

    from django.contrib.auth import logout
    from django.http import HttpRequest
    from django.shortcuts import render
    from django.views.generic.base import TemplateView
    
    
    class SignedOutView(TemplateView):
    
        template_name = "registration/signed_out.html"
    
        def get(self, request: HttpRequest):
            logout(request)
            return render(request, self.template_name)
    

    模板

    registration 文件夹下添加一个新的signed_out.html 模板。

    {% extends "base.html" %}
    
    {% block content %}
    
    <section id="page" class="">
      <p>You are signed out!</p>
    
      <p>Click <a href="{% url 'login' %}">here</a> to sign in again.</p>
    </section>
    
    {% endblock content %}
    

    网址

    更新您的 URL 路径。

    from django.conf.urls import include
    from django.contrib import admin
    from django.urls import path
    
    from .views import SignedOutView
    
    
    urlpatterns = [
        path("accounts/", include('django.contrib.auth.urls')),
        path("admin/", admin.site.urls),
        path("signed-out/", SignedOutView.as_view(), name="sign-out"),
    ]
    

    使用新的退出视图

    <a href="{% url 'sign-out'%}">Sign out</a>
    

    【讨论】:

      【解决方案2】:

      这是适用于 Django 3+ 的解决方案。

      django.contrib.admin 替换为my_admin 模块。

      INSTALLED_APPS = [
              ...
              'my_admin.apps.AdminConfig',
              # 'django.contrib.admin',
              ...
      ]
      

      AdminConfig (my_admin/apps.py):

      from django.contrib.admin.apps import AdminConfig as ContribAdminConfig
      
      class AdminConfig(ContribAdminConfig):
          default_site = 'my_admin.admin_site.AdminSite'
      

      AdminSite (my_admin/admin_site.py):

      from django.contrib.admin import AdminSite as ContribAdminSite
      from django.views.decorators.cache import never_cache
      
      class AdminSite(ContribAdminSite):
          @never_cache
          def logout(self, request, extra_context=None):
              """
              Define your custom logout functionality here.
              Checkout the super logout method to get a baseline implementation.
              
              Log out the user for the given HttpRequest.
              This should *not* assume the user is already logged in.
              """
      
              # Your logout code here.
      
              return super().logout(request, extra_context)
      

      【讨论】:

        【解决方案3】:
        from django.contrib.auth import logout
        
        def custom_logout(request):
            print('Loggin out {}'.format(request.user))
            logout(request)
            print(request.user)
            return HttpResponseRedirect('/restrictedpage')
        
        

        这对我有用,也应该对你有用。

        【讨论】:

          【解决方案4】:

          登录和注销是 Django 的一部分(和 AbstractUser 也是),因此您不需要扩展这部分代码。您必须做的一件事是在 settings.py 文件中添加这两行代码:

          LOGIN_REDIRECT_URL = 'template_name'
          LOGOUT_REDIRECT_URL = 'template_name'
          

          【讨论】:

          • 实际上我将它们设为LOGIN_REDIRECT_URL = '/restrictedpage' LOGOUT_REDIRECT_URL = '/accounts/login' 这并不能解决我的问题,因为问题出在注销时...
          • 在 Django for Beginners Learn web development with Django 2.0 作者 William S. Vincent 作者描述了如何使用 AbstractUser 扩展用户模型。而且他不会在登录或注销视图中更改代码。他直接在模板中使用它们。

            logout

            你用什么方法来扩展用户模型? AbstractUser 还是 AbstractBaseUser?也许你的代码有错误。
          • 我使用了 AbstractUser,因为我在模型中添加了 2 个附加字段。我想我会再次设置该项目以尝试....也许我的项目以某种方式损坏了。
          猜你喜欢
          • 2020-06-01
          • 2014-03-31
          • 1970-01-01
          • 2012-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多