2017-01-14 5 views
0

Я использую Django Rest Framework для создания webapp с регистрацией пользователя/логином. Я пытаюсь освободить пользовательский вид регистрации от необходимости наличия токена CSRF. Это то, что мой взгляд выглядит прямо сейчас:Django csrf_exempt не работает с SessionAuthentication

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.

Почему бы не работать? Может ли это иметь какое-то отношение к тому, что я никогда не устанавливал cookie CSRF вручную?

+0

get_permissions не нуждается в декораторе csrf_exempt? Вы используете метод POST. Вы можете написать @csrf_exempt: [Документация] (https://docs.djangoproject.com/en/1.10/ref/csrf/#django.views.decorators.csrf.csrf_protect) – Wilfried

+0

Вы также можете увидеть [этот пост] (http : //stackoverflow.com/questions/17716624/django-csrf-cookie-not-set) – Wilfried

+0

@Wilfried Я попробовал добавить '@method_decorator (csrf_exempt)' в начало 'get_permissions', но без изменений –

ответ

0

Рамка Django REST уже предотвращает выполнение 0Sпроверки CSRF с использованием csrf_exempt на любых APIView. Вместо этого он явно вызывает проверку CSRF, когда пользователь успешно аутентифицирован с использованием SessionAuthentication. Вы не можете обойти эту проверку и не должны. Регулярное представление Django может не зависеть от сеанса, и в этом случае CSRF-атака невозможна, и вы можете использовать csrf_exempt, чтобы указать это. Когда вы используете SessionAuthentication, вы : уязвимы для атак CSRF, и вам нужна проверка для предотвращения атак. Обход проверки в этом случае неизменно открывает вам уязвимость, поэтому DRF не позволяет вам отключить проверку.

Вы в основном есть два варианта, чтобы исправить это:

  • Убедитесь, что пользователь не успешно заверен SessionAuthentication.
  • Убедитесь, что файл cookie установлен, и отправьте токен в заголовок запроса X-CsrfToken.
+0

Я не понимаю как SessionAuthentication связана с защитой CSRF. Я вижу, что в Django у вас не может быть первого без последнего, но я не понимаю, почему так. –

+1

Атака CSRF - это способ злоупотребления вашей сессией без вашего ведома. Если у вас нет сеанса или подобного механизма, злоумышленник не может злоупотреблять, создавая запрос на межсайтовый сайт. – knbk

+0

Спасибо за объяснение. Делает совершенный смысл. Поэтому просто перефразировать, если он аутентифицирован с помощью функции SessionAuthentication, 'csrf_exempt' не имеет никакого эффекта. В каком сценарии будет полезно использовать 'csrf_exempt'? Согласно тому, что я прочитал, только при использовании «SessionAuthenification» CSRF проверяется, поэтому использование 'csrf_exempt' в противном случае бесполезно, потому что CSRF в любом случае не проверяется. –

Смежные вопросы