如何限制非员工用户访问django-admin
How to restrict non staff users from accessing django-admin
我的 django-admin 页面位于
假设我的网站有 3 个用户。
- 超级用户
- 员工
- 最终用户
如果这三个用户中的任何一个试图访问此 link http://127.0.0.1:8000/admin/,第一个和第二个都可以访问它。
最终用户 无法访问它。到此为止就好了
我想要做的是向最终用户显示错误 404。 He/She 永远不会知道这个 link 是用于管理页面的。此外,如果任何人未登录,他们也应该看到相同的 404 页面。
我已经提到 this link 但它会将我带到另一个默认页面。
PFA 同样
PS:我正在使用 Signin With Google,所以它不应该将我重定向到那里。
我连续 3 天都在尝试这个,所以非常感谢任何帮助。提前致谢。
Django 版本:3.0.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
接下来我们将按照您的链接问题中的描述使用此装饰器:
from django.contrib import admin
admin.site.login = staff_required(admin.site.login)
urlpatterns = [
path('admin/', admin.site.urls),
]
Edit:上面的方法有点老套,即使出现 404 错误,它也会向用户显示登录页面 url。最好制作一个自定义管理站点 class 并使用它。管理站点有一个方法 admin_view
装饰我们将覆盖的管理视图。我们将在项目主应用程序的文件 admin.py
中执行此操作(假设项目名为 myproject
)
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)
现在我们需要用我们的自定义管理站点替换默认管理站点。为此,我们将遵循 Overriding the default admin site [Django docs]:
在项目主应用程序的 apps.py
文件中(假设项目被命名为 myproject
):
from django.contrib.admin.apps import AdminConfig
class MyAdminConfig(AdminConfig):
default_site = 'myproject.admin.MyAdminSite'
现在 settings.py
我们将用我们自己的配置替换 'django.contrib.admin'
class:
INSTALLED_APPS = [
...
'myproject.apps.MyAdminConfig', # replaces 'django.contrib.admin'
...
]
我的 django-admin 页面位于
假设我的网站有 3 个用户。
- 超级用户
- 员工
- 最终用户
如果这三个用户中的任何一个试图访问此 link http://127.0.0.1:8000/admin/,第一个和第二个都可以访问它。 最终用户 无法访问它。到此为止就好了
我想要做的是向最终用户显示错误 404。 He/She 永远不会知道这个 link 是用于管理页面的。此外,如果任何人未登录,他们也应该看到相同的 404 页面。
我已经提到 this link 但它会将我带到另一个默认页面。
PFA 同样
PS:我正在使用 Signin With Google,所以它不应该将我重定向到那里。
我连续 3 天都在尝试这个,所以非常感谢任何帮助。提前致谢。
Django 版本:3.0.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
接下来我们将按照您的链接问题中的描述使用此装饰器:
from django.contrib import admin
admin.site.login = staff_required(admin.site.login)
urlpatterns = [
path('admin/', admin.site.urls),
]
Edit:上面的方法有点老套,即使出现 404 错误,它也会向用户显示登录页面 url。最好制作一个自定义管理站点 class 并使用它。管理站点有一个方法 admin_view
装饰我们将覆盖的管理视图。我们将在项目主应用程序的文件 admin.py
中执行此操作(假设项目名为 myproject
)
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)
现在我们需要用我们的自定义管理站点替换默认管理站点。为此,我们将遵循 Overriding the default admin site [Django docs]:
在项目主应用程序的 apps.py
文件中(假设项目被命名为 myproject
):
from django.contrib.admin.apps import AdminConfig
class MyAdminConfig(AdminConfig):
default_site = 'myproject.admin.MyAdminSite'
现在 settings.py
我们将用我们自己的配置替换 'django.contrib.admin'
class:
INSTALLED_APPS = [
...
'myproject.apps.MyAdminConfig', # replaces 'django.contrib.admin'
...
]