如何限制非员工用户访问 django-admin

aji*_*hod 4 django django-admin

我的 django-admin 页面位于

http://127.0.0.1:8000/admin/

假设我的网站有 3 个用户。

  1. 超级用户
  2. 职员
  3. 最终用户

如果这三个用户中的任何一个尝试访问此链接http://127.0.0.1:8000/admin/,则第一个和第二个用户可以访问它。最终用户无法访问它。到这为止,就好了。

我想要做的是向最终用户显示 Error 404 。他/她永远不应该知道此链接用于管理页面。此外,如果有人没有登录,他们也应该看到相同的 404 页面。

我已引用链接,但它带我到另一个默认页面。

PFA 相同


在此输入图像描述


PS:我正在使用Signin With Google,所以它不应该将我重定向到那里。

我连续三天都在尝试这个,所以非常感谢您的帮助。提前致谢。

Django 版本:3.0.5

Abd*_*kat 5

您首先需要创建一个自定义装饰器,如果用户不是员工,它会给出 404:

from django.http import Http404
from functools import wraps

def staff_required(func):
    @wraps(func)
    def wrapper(request, *args, **kwargs):
        if request.user.is_staff:
            return func(request, *args, **kwargs)
        raise Http404()
    return wrapper
Run Code Online (Sandbox Code Playgroud)

接下来,我们将按照您的链接问题中的描述使用此装饰器:

from django.contrib import admin

admin.site.login = staff_required(admin.site.login)

urlpatterns = [
    path('admin/', admin.site.urls),
]
Run Code Online (Sandbox Code Playgroud)

编辑:上面的方法有点 hacky,即使给出 404 错误,它也会向用户显示登录页面 url。最好制作一个自定义管理站点类并使用它。管理站点有一个方法admin_view来装饰我们将覆盖的管理视图。我们将在项目主应用程序的文件中执行此操作admin.py(假设该项目名为myproject

from django.http import Http404
from functools import wraps

def staff_required(func):
    @wraps(func)
    def wrapper(request, *args, **kwargs):
        if request.user.is_staff:
            return func(request, *args, **kwargs)
        raise Http404()
    return wrapper
Run Code Online (Sandbox Code Playgroud)

现在我们需要用我们的自定义管理站点替换默认管理站点。为此,我们将遵循覆盖默认管理站点 [Django 文档]

在项目主应用程序的apps.py文件中(假设项目名为myproject):

from django.contrib import admin

admin.site.login = staff_required(admin.site.login)

urlpatterns = [
    path('admin/', admin.site.urls),
]
Run Code Online (Sandbox Code Playgroud)

现在settings.py我们将替换'django.contrib.admin'为我们自己的配置类:

from functools import update_wrapper

from django.contrib import admin
from django.http import (
    Http404, HttpResponseRedirect,
)
from django.urls import reverse
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect


class MyAdminSite(admin.AdminSite):
    def admin_view(self, view, cacheable=False):
        def inner(request, *args, **kwargs):
            if not self.has_permission(request):
                if request.path == reverse('admin:logout', current_app=self.name):
                    index_path = reverse('admin:index', current_app=self.name)
                    return HttpResponseRedirect(index_path)
                raise Http404()
            return view(request, *args, **kwargs)
        if not cacheable:
            inner = never_cache(inner)
        # We add csrf_protect here so this function can be used as a utility
        # function for any view, without having to repeat 'csrf_protect'.
        if not getattr(view, 'csrf_exempt', False):
            inner = csrf_protect(inner)
        return update_wrapper(inner, view)
Run Code Online (Sandbox Code Playgroud)