Shy*_*net 5 python django csrf
我开发了一个简单的 web 服务,但未能在 Django Rest Framework 中使用 post,因为它抱怨 CSRF:
"detail": "CSRF 失败:CSRF cookie 未设置。"
删除 api_view 装饰器确实会阻止消息出现,但随后我将无法访问 request.data。尽管我添加了 csrf_exempt 装饰器,但我认为 api_view 确实会检查 CSRF。
这是我的观点:
@permission_classes((IsAuthenticated, ))
@csrf_exempt
@api_view(['POST'])
def get_stats(request):
"""
Returns the stats available.
"""
user = request.user
if request.method == 'POST':
serializer = StatsRequestSerializer(data=request.data)
stats_request = serializer.data
return JSONResponse(stats_request)
#serializer = QuizSerializer(user.quizes.all(), many=True)
#return JSONResponse(serializer.data)
response = ActionResponse(status='error', error='Invalid request')
serializer = ActionResponseSerializer(response)
return JSONResponse(serializer.data, status=400)
Run Code Online (Sandbox Code Playgroud)
这是我的模型:
class StatsRequest(models.Model):
"""
A model which describes a request for some stats for specific users.
"""
start_date = models.DateField()
end_date = models.DateField()
Run Code Online (Sandbox Code Playgroud)
这是我的请求 POST:
{"start_date" : "1992-01-15", "end_date" : "1992-01-15" }
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
更多信息:
AUTHENTICATION_BACKENDS = (
'social.backends.facebook.FacebookOAuth2',
'social.backends.google.GoogleOAuth2',
'django.contrib.auth.backends.ModelBackend'
)
Run Code Online (Sandbox Code Playgroud)
因此,在尝试了几个小时后,我终于做到了。跟踪 DRF 和 Django 的源代码让我相信我需要找到解决方法,因为即使关闭了 CSRF 验证,CSRF 验证也会明确进行,可能是在 api_view 装饰器中进行 CSRF 检查。所以我简单地创建了自己的装饰器:
from functools import wraps
from django.utils.decorators import available_attrs, decorator_from_middleware
def csrf_clear(view_func):
"""
Skips the CSRF checks by setting the 'csrf_processing_done' to true.
"""
def wrapped_view(*args, **kwargs):
request = args[0]
request.csrf_processing_done = True
return view_func(*args, **kwargs)
return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)
Run Code Online (Sandbox Code Playgroud)
以及我对新装饰器的看法:
@csrf_clear
@api_view(['POST'])
@permission_classes((IsAuthenticated, ))
def get_stats(request):
"""
Returns the stats available.
"""
user = request.user
if request.method == 'POST':
serializer = StatsRequestSerializer(data=request.data)
if serializer.is_valid():
stats_request = serializer.data
return JSONResponse(stats_request)
#serializer = QuizSerializer(user.quizes.all(), many=True)
#return JSONResponse(serializer.data)
response = ActionResponse(status='error', error='Invalid request')
serializer = ActionResponseSerializer(response)
return JSONResponse(serializer.data, status=400)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3102 次 |
| 最近记录: |