我想设置一个带有 REST API 的简单 Django 后端。如果我尝试使用提供的 url 登录,但每次尝试登录时都会收到 403 错误:CSRF Verficatoin 失败。 CSRF cookie 未设置。
这是我用过的应用程序:
Django==4.1.10
# Rest Framework
djangorestframework==3.14.0
djangorestframework-api-key==2.3.0
djangorestframework-simplejwt==5.2.2
markdown==3.4.4
# CORS for rest api
django-cors-headers==4.2.0
和我的设置:
ALLOWED_HOSTS='*, localhost'
ALLOWED_ORIGINS='http://*, https://*'
CSRF_COOKIE_AGE=31449600
CSRF_COOKIE_NAME='csrftoken'
CSRF_USE_SESSIONS=False
CSRF_TRUSTED_ORIGINS='http://*, https://*'
CSRF_COOKIE_HTTPONLY=False
CSRF_COOKIE_SECURE=False
CSRF_COOKIE_DOMAIN = None
CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN'
CORS_ALLOW_ALL_ORIGINS=False
CORS_ALLOWED_ORIGIN_REGEXES=''
CORS_ALLOWED_ORIGINS='http://localhost:8888, http://127.0.0.1:8888'
服务器在端口 8888 上运行,命令为:python3 manage.py runserver 0.0.0.0:8888
中间件:
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',
]
以及 Rest Framework 的设置:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework_api_key.permissions.HasAPIKey',
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
# 'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.BasicAuthentication', # only for testing
],
"DEFAULT_PARSER_CLASSES": [
"rest_framework.parsers.JSONParser",
"rest_framework.parsers.FormParser",
"rest_framework.parsers.MultiPartParser",
],
}
这些网址在应用程序的介绍中:
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
现在,如果我尝试以下请求:
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "my_username", "password": "my_password"}' \
http://localhost:8888/api/token/
我收到错误代码 403,如上所述。
你有什么想法吗?我该如何解决这个问题?
致以诚挚的问候!
经过几个小时的测试,我找到了解决方案。 url 模式的顺序错误。我将其更改为:
urlpatterns = [
path('', admin.site.urls),
path('api/token/', csrf_exempt(TokenObtainPairView.as_view()), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]
至:
urlpatterns = [
path('api/token/', csrf_exempt(TokenObtainPairView.as_view()), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
path('', admin.site.urls),
]
管理站点必须是最后一个条目,我删除了登录网址的 csrf 豁免。
谢谢阿蒂沙姆的回复。