如何全局保护Wagtail企业内网站点并强制页面私有状态
解决方案:Wagtail站点全站私有化及强制页面权限控制
一、将整个站点设置为Private
方法1:使用Django全局中间件拦截未认证请求
这种方式对所有前端页面生效,无需修改现有页面模型,适合大规模站点快速部署:
- 在项目根目录创建
middleware.py,添加以下代码:
from django.shortcuts import redirect from django.conf import settings class RequireLoginMiddleware: def __init__(self, get_response): self.get_response = get_response # 排除登录页及必要的公开路径(根据实际情况调整) self.exempt_paths = [ settings.LOGIN_URL, # 内网环境建议不公开静态资源,如需公开可添加'/static/' ] def __call__(self, request): if not request.user.is_authenticated: path = request.path_info if not any(path.startswith(exempt) for exempt in self.exempt_paths): # 重定向到登录页,携带原路径以便登录后跳转 return redirect(f"{settings.LOGIN_URL}?next={path}") response = self.get_response(request) return response
- 在
settings.py的MIDDLEWARE列表中添加该中间件(需放在django.contrib.auth.middleware.AuthenticationMiddleware之后):
MIDDLEWARE = [ # ... 其他中间件 ... 'django.contrib.auth.middleware.AuthenticationMiddleware', 'your_project_name.middleware.RequireLoginMiddleware', # ... 其他中间件 ... ]
方法2:使用Wagtail页面钩子精准控制
如果需要仅对前端页面生效,不影响Wagtail管理后台,可使用Wagtail的before_serve_page钩子:
在项目的wagtail_hooks.py中添加:
from wagtail.core import hooks from django.shortcuts import redirect from django.conf import settings @hooks.register('before_serve_page') def require_login_for_public_pages(page, request, serve_args, serve_kwargs): if not request.user.is_authenticated: return redirect(f"{settings.LOGIN_URL}?next={request.path}")
这个钩子会在每个前端页面渲染前触发,强制未认证用户跳转至登录页。
二、禁止页面设置为Public,强制仅对已认证用户可见
步骤1:批量移除现有页面的匿名访问权限
当前所有页面标记为public,意味着匿名用户(AnonymousUser)拥有查看权限,需批量清理:
- 在
manage.py shell中执行以下代码(或保存为脚本文件运行):
from django.contrib.auth.models import AnonymousUser, Group from wagtail.models import Page # 获取/创建认证用户组 auth_group, _ = Group.objects.get_or_create(name='Authenticated Users') # 优先修改根页面权限(子页面会自动继承),无需遍历所有30000个页面 root_page = Page.objects.get(id=1) # 移除匿名用户的查看权限 anon_perm = root_page.permissions.filter(user=AnonymousUser()).first() if anon_perm: root_page.permissions.remove(anon_perm) # 添加认证用户组的查看权限 root_page.permissions.add(root_page.permissions.get_or_create( user=auth_group, permission_type='view' )[0])
步骤2:禁用后台设置匿名权限的入口
为防止后续误操作添加匿名权限,拦截后台的权限设置表单:
在wagtail_hooks.py中添加:
from wagtail.core import hooks @hooks.register('construct_page_permissions_form') def restrict_anonymous_permissions(form_class, page): # 从权限表单的用户选项中移除匿名用户 form_class.base_fields['user'].queryset = form_class.base_fields['user'].queryset.exclude(is_anonymous=True)
步骤3:强制页面模型无公开选项(若有自定义public字段)
如果页面模型自定义了public布尔字段,需将其设为不可编辑且默认关闭:
修改页面模型:
from wagtail.models import Page from django.db import models class BasePage(Page): # 将public字段设为不可编辑,默认False public = models.BooleanField(default=False, editable=False) content_panels = Page.content_panels + [ # 移除原有的public字段面板(若之前添加过) ] class Meta: abstract = True
运行迁移命令更新数据库:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者frague
相关产品推荐
相关产品推荐

