1. 程式人生 > >解決Django + DRF:403 FORBIDDEN:CSRF令牌丟失或不正確,{"detail":"CSRF Failed: CSRF cookie not set."}

解決Django + DRF:403 FORBIDDEN:CSRF令牌丟失或不正確,{"detail":"CSRF Failed: CSRF cookie not set."}

 

我有一個Android客戶端應用程式嘗試使用Django + DRF後端進行身份驗證。但是,當我嘗試登入時,我收到以下響應:

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' ), } 

django django-rest-framework csrf django-allauth django-rest-auth 
 | 
  這個問題是
2015年 9月16日7:15問題 manabreak 1,858 1 12 38



 | 

答案
2

你為什麼會收到這個錯誤?

由於您尚未AUTHENTICATION_CLASSES在設定中定義,DRF使用以下預設身份驗證類。

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

現在,SessionAuthentication強制使用CSRF Token如果未傳遞有效的CSRF令牌,則會引發403錯誤。

如果您使用的是AJAX風格的API有SessionAuthentication,你需要確保你有一個有效的CSRF令牌任何“不安全”的HTTP方法呼叫,如PUTPATCHPOSTDELETE請求。

那你需要做什麼?

由於您正在使用TokenAuthentication,您需要AUTHENTICATION_CLASSES在DRF設定中明確定義它這應該可以解決您的CSRF令牌問題。



  這個答案
 編輯於2015年 9月16日16:45回答2015年 9月16日7:27 Rahul Gupta 17k 2 25 33你說我們必須傳遞一個有效的CSRF令牌。我在哪裡可以找到這個令牌?在我的情況下,當我嘗試使用端點登入時出現問題 但它是客戶端和伺服器之間的第一次聯絡,因此客戶端不知道令牌。-  Ben Jan 4 at 13:37檢查這個Django docs連結以獲取Ajax請求的CSRF令牌。-  Rahul Gupta 1月4日14:34謝謝@ rahul-gupta,但我不在網路環境中。我在ac#environment(Xamarin)。但無論如何,在休息<>客戶端應用程式中,如果伺服器沒有告訴他,客戶端就無法知道csrf。-  rest-auth/login/BenJan 4 at 17:31然後您應該使用不同的身份驗證類,因為SessionAuthentication需要傳送CSRF令牌。您需要在設定或特定檢視中明確定義該特定身份驗證類。-  Rahul Gupta 1月4日17:59



 |  解決方法

傻了,我錯過TokenAuthentication了REST設定中框架:

settings.py

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

現在它按預期工作。