Django GraphQL API的CSRF防护及后端调用Token获取咨询
问题解答
一、豁免CSRF后是否仍有CSRF攻击防护能力?
这取决于你的Token认证实现方式:
- 如果Token是通过自定义HTTP Header(比如
Authorization: Bearer <token>)传递的:这种情况下即使加了csrf_exempt,也不会有CSRF风险。因为CSRF攻击的核心是利用浏览器自动携带Cookie的特性,而跨域请求中浏览器会阻止自定义Header的伪造(同源策略限制),攻击者无法在跨域请求中注入你的Token Header,所以API是安全的。 - 如果Token是存在Cookie中的:这种情况即使有Token认证,开启
csrf_exempt后依然存在CSRF风险。因为浏览器会自动在跨域请求中携带Cookie,攻击者可以构造恶意请求触发CRUD操作,而你的API会验证Cookie里的Token并执行操作。
二、无需前端传递CSRF Token的验证方案
如果不想用csrf_exempt,针对后端之间的调用场景,有以下几种可行方案:
1. 基于Token认证跳过CSRF检查
既然你的API已经采用Token认证,直接配置Django(或graphene-django)使用TokenAuthentication类,这类认证方式不依赖CSRF机制,天然免疫CSRF攻击。
- 配置示例(以graphene-django为例):
这种方式下,只要请求携带有效的Token Header,就会通过认证,无需CSRF Token,同时也不会有CSRF风险。from rest_framework.authentication import TokenAuthentication from graphene_django.views import GraphQLView class CustomGraphQLView(GraphQLView): authentication_classes = [TokenAuthentication] # 在urls.py中替换默认GraphQLView urlpatterns = [ path("graphql/", CustomGraphQLView.as_view(graphiql=True)), ]
2. 针对后端调用自定义权限校验
如果必须保留CSRF机制,可以在视图层针对后端请求来源做特殊处理:
- 检查请求的来源IP,只允许可信的后端IP访问API;
- 或者在请求中携带一个后端专属的密钥(比如自定义Header
X-Backend-Secret),验证通过后跳过CSRF检查。 - 示例代码:
from django.views.decorators.csrf import csrf_exempt, csrf_protect def csrf_exempt_for_backend(view_func): def wrapped_view(request, *args, **kwargs): # 检查是否是后端请求,比如验证自定义密钥或IP if request.META.get("X-Backend-Secret") == "YOUR_SECRET_KEY": return csrf_exempt(view_func)(request, *args, **kwargs) # 其他请求走正常CSRF校验 return csrf_protect(view_func)(request, *args, **kwargs) return wrapped_view # 给GraphQL视图添加这个装饰器
3. 后端主动获取CSRF Token再调用
如果一定要使用Django的CSRF验证流程,可以让调用方的后端先主动请求Django的CSRF Token接口,再携带Token发起CRUD请求:
- 先写一个简单的接口返回CSRF Token:
from django.http import JsonResponse from django.middleware.csrf import get_token def get_csrf_token(request): return JsonResponse({"csrfToken": get_token(request)}) - 后端调用方先请求这个接口拿到Token,然后在后续GraphQL请求的
X-CSRFTokenHeader中携带该Token即可完成验证,全程不需要前端参与。
内容的提问来源于stack exchange,提问作者keita063
相关产品推荐
相关产品推荐

