3

У меня есть клиентское приложение для Android, которое пытается выполнить аутентификацию с помощью брандмауэра Django + DRF. Однако, когда я пытаюсь войти в систему, я получаю следующий ответ:Django + DRF: 403 ЗАПРЕЩЕНО: токен CSRF отсутствует или неверен

403: CSRF Failed: CSRF token missing or incorrect. 

Запрос отправляется http://localhost/rest-auth/google/ со следующим телом:

access_token: <the OAuth token from Google> 

Что могло вызвать это? Клиент не имеет токена CSRF, поскольку проверка подлинности POST является первым делом между клиентом и сервером. Я проверил много прошлых вопросов с той же проблемой, но я не мог найти никаких решений.

Соответствующие настройки на стороне Django, как это:

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend", 
    "allauth.account.auth_backends.AuthenticationBackend" 
) 

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.request", 
    "django.contrib.auth.context_processors.auth", 
    "allauth.account.context_processors.account", 
    "allauth.socialaccount.context_processors.socialaccount" 
) 

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
) 

INSTALLED_APPS = (
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.sites', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'app', 
    'allauth', 
    'allauth.account', 
    'allauth.socialaccount', 
    'allauth.socialaccount.providers.facebook', 
    'allauth.socialaccount.providers.google', 

    'django.contrib.admin', 

    # REST framework 
    'rest_framework', 
    'rest_framework.authtoken', 
    'rest_auth', 
    'rest_auth.registration', 
) 

REST_FRAMEWORK = { 
    'DEFAULT_PERMISSION_CLASSES': ( 
     'rest_framework.permissions.IsAuthenticated' 
    ), 
} 

ответ

1

Глупый меня, я пропустил TokenAuthentication рамки с настройками REST:

settings.py

REST_FRAMEWORK = { 
    'DEFAULT_AUTHENTICATION_CLASSES': (
     'rest_framework.authentication.TokenAuthentication', 
    ) 
} 

Теперь он работает так, как предполагалось.

3

Почему вы получаете эту ошибку?

Как вы еще не определили AUTHENTICATION_CLASSES в своих настройках, DRF использует следующие классы аутентификации по умолчанию.

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication', 
    'rest_framework.authentication.BasicAuthentication' 
) 

Теперь SessionAuthentication навязывает использование CSRF Token. Если вы не передаете действительный токен CSRF, тогда возникает ошибка 403.

Если вы используете стиль API AJAX с SessionAuthentication, вы должны убедиться, что вы включили действительный маркер CSRF для любых «опасных» HTTP вызовов методов, такие как PUT, PATCH, POST или DELETE запросов.

Что вам нужно сделать тогда?

Поскольку вы используете TokenAuthentication, вам необходимо явно определить его в AUTHENTICATION_CLASSES в настройках DRF. Это должно устранить проблему с токеном CSRF.

+0

Вы говорите, что мы должны передать действительный токен CSRF. Где я могу найти этот токен? В моем случае проблема возникает, когда я пытаюсь войти в систему с 'rest-auth/login /' endpoint. Но это первый контакт между клиентом и сервером, поэтому клиент не знает токена. – Ben

+0

Проверьте этот документ Django [link] (https://docs.djangoproject.com/en/1.10/ref/csrf/#ajax), чтобы получить токен CSRF для запросов Ajax. –

+0

Спасибо @ rahul-gupta, но я не в веб-среде. Я нахожусь в среде C# (Xamarin). Но в любом случае, в клиентском приложении отдыха <> клиент не может знать csrf, если сервер ему не сказал. – Ben

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