Django csrf_exempt 不使用 SessionAuthentication
Django csrf_exempt not working with SessionAuthentication
我正在使用 Django Rest Framework 与用户 registration/login 一起构建一个网络应用程序。
我试图免除用户注册视图需要 CSRF 令牌。这就是我现在的观点:
class UserSignUpView(generics.CreateAPIView):
permission_classes = [] # FIXME: doesn't seem to be working
serializer_class = UserSerializer
@method_decorator(csrf_exempt)
def post(self, request, *args, **kwargs):
super().post(self, request, *args, **kwargs)
def get_permissions(self):
if self.request.method == 'POST':
return (permissions.AllowAny(), TokenHasReadWriteScope())
return False
我的 settings.py 看起来像这样:
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
我仍然在后端输出 Forbidden (CSRF cookie not set.): /users/
和前端输出经典 CSRF verification failed. Request aborted.
为什么这行不通?这可能与我从未手动设置 CSRF cookie 的事实有关吗?
Django REST 框架已经通过在任何 APIView
上使用 csrf_exempt
来阻止 CSRFViewMiddleware
执行 CSRF 检查。相反,当用户使用 SessionAuthentication
成功验证时,它会显式调用 CSRF 检查。你不能绕过这个检查,你也不应该。常规 Django 视图可能不依赖于 session,在这种情况下,CSRF 攻击是不可能的,您可以使用 csrf_exempt
来指示这一点。当您使用 SessionAuthentication
时,您 是 容易受到 CSRF 攻击,您需要检查以防止攻击。在这种情况下绕过检查总是会给您带来漏洞,这就是 DRF 不允许您禁用检查的原因。
你基本上有两种选择来解决这个问题:
- 确保用户未通过
SessionAuthentication
成功验证。
- 确保已设置 cookie,并在
X-CsrfToken
请求 header 中发送令牌。
我正在使用 Django Rest Framework 与用户 registration/login 一起构建一个网络应用程序。 我试图免除用户注册视图需要 CSRF 令牌。这就是我现在的观点:
class UserSignUpView(generics.CreateAPIView):
permission_classes = [] # FIXME: doesn't seem to be working
serializer_class = UserSerializer
@method_decorator(csrf_exempt)
def post(self, request, *args, **kwargs):
super().post(self, request, *args, **kwargs)
def get_permissions(self):
if self.request.method == 'POST':
return (permissions.AllowAny(), TokenHasReadWriteScope())
return False
我的 settings.py 看起来像这样:
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
我仍然在后端输出 Forbidden (CSRF cookie not set.): /users/
和前端输出经典 CSRF verification failed. Request aborted.
为什么这行不通?这可能与我从未手动设置 CSRF cookie 的事实有关吗?
Django REST 框架已经通过在任何 APIView
上使用 csrf_exempt
来阻止 CSRFViewMiddleware
执行 CSRF 检查。相反,当用户使用 SessionAuthentication
成功验证时,它会显式调用 CSRF 检查。你不能绕过这个检查,你也不应该。常规 Django 视图可能不依赖于 session,在这种情况下,CSRF 攻击是不可能的,您可以使用 csrf_exempt
来指示这一点。当您使用 SessionAuthentication
时,您 是 容易受到 CSRF 攻击,您需要检查以防止攻击。在这种情况下绕过检查总是会给您带来漏洞,这就是 DRF 不允许您禁用检查的原因。
你基本上有两种选择来解决这个问题:
- 确保用户未通过
SessionAuthentication
成功验证。 - 确保已设置 cookie,并在
X-CsrfToken
请求 header 中发送令牌。