如何为Wagtail API V2添加密钥认证,仅限内部授权服务访问
为Wagtail API V2添加共享密钥认证的可行方案
方案一:用Django中间件做URL层面校验(推荐,不受Wagtail版本更新影响)
这个方法不需要改动Wagtail的API视图代码,直接在中间件里拦截所有API路径,校验请求里的共享密钥,符合要求才放行,完美解决你不想碰视图层的需求。
- 新建自定义中间件文件:
# 你的app目录下新建middleware.py from django.http import HttpResponseForbidden from django.conf import settings class APISecretKeyMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 匹配你的Wagtail API前缀,默认是/api/v2/,根据实际配置调整 if request.path.startswith('/api/v2/'): # 从请求头拿密钥,也可以改成从GET参数(比如?api_key=xxx)获取 provided_key = request.headers.get('X-API-SECRET') valid_key = settings.API_SECRET_KEY if not provided_key or provided_key != valid_key: return HttpResponseForbidden("无效或缺失API密钥") response = self.get_response(request) return response
- 在settings.py里注册这个中间件,注意放在合适的位置(比如CommonMiddleware之后):
MIDDLEWARE = [ # ... 其他已有中间件 'your_app_name.middleware.APISecretKeyMiddleware', ] # 添加你的共享密钥,记得设成复杂字符串 API_SECRET_KEY = "your-strong-secret-key-here"
- 其他服务调用API时,只需要在请求头里带上
X-API-SECRET: your-strong-secret-key-here即可。
方案二:修复Wagtail视图集的认证问题
如果一定要通过修改视图集实现,之前的错误是因为Wagtail的API视图集通过get_urlpatterns生成路由,直接加@login_required不生效。你可以重写视图集的dispatch方法来做密钥校验:
# 你的app下新建api/views.py from wagtail.api.v2.views import PagesAPIViewSet from django.http import HttpResponseForbidden from django.conf import settings class CustomPagesAPIViewSet(PagesAPIViewSet): def dispatch(self, request, *args, **kwargs): provided_key = request.headers.get('X-API-SECRET') if not provided_key or provided_key != settings.API_SECRET_KEY: return HttpResponseForbidden("无效或缺失API密钥") return super().dispatch(request, *args, **kwargs)
然后在urls.py里替换默认的API路由:
from wagtail.api.v2.router import WagtailAPIRouter from your_app.api.views import CustomPagesAPIViewSet api_router = WagtailAPIRouter('wagtailapi') api_router.register_endpoint('pages', CustomPagesAPIViewSet) urlpatterns = [ # ... 其他路由 path('api/v2/', api_router.urls), ]
额外提示
- 中间件方案更稳妥,后续Wagtail版本更新时,不需要修改这部分代码。
- 共享密钥一定要足够复杂,避免被暴力破解,同时确保服务间用HTTPS传输请求。
- 如果需要支持多个合法密钥,可以把settings里的
API_SECRET_KEY改成列表,然后判断provided_key in settings.API_SECRET_KEYS。
内容的提问来源于stack exchange,提问作者pyreho
相关产品推荐
相关产品推荐

