我正在托管一个React应用(http://localhost:3000/),并希望使用http://127.0.0.1:8000/调用从Django REST应用(fetch)中对用户进行身份验证。我正在使用django-cors-headers
解决CORS问题,但仍然遇到403 Forbidden (CSRF cookie not set.): /api-auth/login/
错误/
我的用户是django.contrib.auth.models.AbstractUser
的直接子类,我正在使用rest_framework.urls
LoginView登录用户。如果我从内置的Django模板(http://127.0.0.1:8000/api-auth/login/ )我可以成功登录,但是当我使用fetch从React应用发布时,出现403错误。
我使用django-core-headers进行CORS挑战,但似乎并没有将Cookie连同响应发送回去。
我尝试使用邮递员(Postman)发送到http://127.0.0.1:8000/api-auth/login/,该邮递员也收到403错误。
urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('users.urls')),
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
settings.py的一部分:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'users',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
AUTH_USER_MODEL = 'users.User'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
}
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_SAMESITE = None
CSRF_TRUSTED_ORIGINS = [
'localhost:3000',
'127.0.0.1:3000',
]
我正在使用fetch调用API。
handleLogin (e) {
e.preventDefault();
fetch('http://127.0.0.1:8000/api-auth/login/', {
method: 'POST',
credentials: 'include',
headers: {
'X-CSRFToken': Cookies.get('csrftoken'),
'Content-Type': 'application/json',
},
body: JSON.stringify(this.state)
})
.then(response => {
console.log(response.body)
return response
})
}
从http://127.0.0.1:8000/调用DRF时可以正确验证用户身份,因此我相信DRF应用程序可以按预期工作。有人可以帮助我解决React应用程序与DRF之间的连接吗?
答案 0 :(得分:1)
您的react应用必须使用适当的终结点从服务器请求csrftoken并存储此cookie。
例如:
# Django view.py
def get_csrf(request):
return HttpResponse("{0}".format(csrf.get_token(request)), content_type="text/plain")
# Django urls.py
url(r'^api/get_csrf/?$', get_csrf, name="get_csrf"),
JS代码:
$.get( "api/get_csrf/", function(data) {
Cookies.set('csrftoken', data);
});