英文:
Django Rest Framework: All POST APIs only respond with "Forbidden" after logging in a user
问题
After enabling authentication in my Django backend and logging in a user all POST Requests stop to work and only respond with "403 Forbidden".
我在Django后端启用了身份验证并登录用户后,所有的POST请求都停止工作,只返回"403 Forbidden"。
I setup a Django App as my backend and I use ReactJS as my Frontend.
All the basics work fine so far.
But now I want to add authentication to my project.
For this I have installed django-cors-headers
.
I have also included corsheaders
in my INSTALLED_APPS
.
CORS_ALLOWED_ORIGINS
allows http://localhost:3000
(the port my Frontend is running under).
CORS_ALLOW_CREDENTIALS
is also set to TRUE
.
The corresponding middleware corsheaders.middleware.CorsMiddleware
has also been added to the MIDDLEWARE
section.
我将Django应用程序设置为后端,使用ReactJS作为前端。到目前为止,一切基本工作正常。但现在我想在项目中添加身份验证。为此,我已安装了django-cors-headers
。我还在INSTALLED_APPS
中包含了corsheaders
。CORS_ALLOWED_ORIGINS
允许http://localhost:3000
(我的前端运行的端口)。CORS_ALLOW_CREDENTIALS
也设置为TRUE
。相应的中间件corsheaders.middleware.CorsMiddleware
也已添加到MIDDLEWARE
部分。
I created three APIs. One each for registering a new user, for logging in an existing user and for logging out a user. All three of them work perfectly fine as long as no user is logged in. The cookies csrftoken
and sessionid
are set just as they should.
我创建了三个API,一个用于注册新用户,一个用于登录现有用户,另一个用于注销用户。只要没有用户登录,它们三者都能正常工作。csrftoken
和sessionid
这两个cookie设置得正常。
Now for my problem:
As soon as a user is logged in all POST APIs - including the three mentioned above - stop to work. I get a simple "403 Forbidden" response. GET APIs seem to work just fine. My research suggests that this is a common error that has something to do with the csrftoken
, yet I can't seem to get it to work, even after multiple evenings of working on this and trying everything that I could find.
I think I narrowed it down to my specific issue, even though I don't know if this really is the problem. When I test the APIs not by using them in my React frontend but instead use the frontend that is included with Django to test the APIs they all work just fine, with or without a logged-in user.
So I compared both requests in the Network task window of my browser (Firefox) and there is only one difference I could find. Both requests obviously send the csrftoken
cookie. Both also send the X-CSRFToken
header, but the value for the header is different for both requests. In the request I send through React, the value for the X-CSRFToken
header is the same as the value of the csrftoken
. In the request through the Django Frontend, the value for the X-CSRFToken
header is different from the value for the csrftoken
cookie.
However, I can't seem to figure out why that is and if this even is the root of my problem.
现在是我的问题:
一旦用户登录,所有的POST API - 包括上面提到的三个 - 都停止工作。我只得到一个简单的"403 Forbidden"响应。GET API似乎工作正常。我的研究表明,这是一个常见错误,与csrftoken
有关,但即使在多个晚上的工作和尝试了所有我能找到的方法后,我似乎无法让它正常工作。
我认为我已经把问题缩小到了特定问题,尽管我不知道这是否真的是问题的根本原因。当我测试API时,不是在我的React前端中使用它们,而是使用Django附带的前端来测试API时,它们都可以正常工作,无论是否有用户登录。
因此,我在浏览器(Firefox)的网络任务窗口中比较了这两个请求,我只找到了一个区别。显然,这两个请求都发送了csrftoken
cookie。它们还都发送了X-CSRFToken
头部,但头部的值对这两个请求不同。在我通过React发送的请求中,X-CSRFToken
头部的值与csrftoken
的值相同。在通过Django前端发送的请求中,X-CSRFToken
头部的值与csrftoken
cookie的值不同。
然而,我似乎无法弄清楚为什么会这样,以及是否这确实是我的问题的根本原因。
As an additional information: I use axios for my HTTP-Requests. For this, I included the following lines of code:
额外的信息:我使用axios进行HTTP请求。为此,我包含了以下代码行:
axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN';```
作为额外信息:我使用axios进行HTTP请求。为此,我包含了以下代码行:
```axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN';```
I'm at my wits' end, no solution I could find on Google or even with Chat-GPT's help seems to solve my problem. So here's hoping someone can point out my mistake for me.
我已经陷入了困境,无论我在Google上找到什么解决方法,甚至是Chat-GPT的帮助,都似乎无法解决我的问题。因此,希望有人能指出我的错误。
<details>
<summary>英文:</summary>
After enabling authentication in my Django backend and logging in a user all POST Requests stop to work and only respond with "403 Forbidden".
I setup a Django App as my backend and I use ReactJS as my Frontend.
All the basics work fine so far.
But now I want to add authentication to my project.
For this I have installed `django-cors-headers`.
I have also included `corsheaders` in my `INSTALLED_APPS`.
`CORS_ALLOWED_ORIGINS` allows `http://localhost:3000` (the port my Frontend is running under).
`CORS_ALLOW_CREDENTIALS` is also set to `TRUE`.
The corresponding middleware `corsheaders.middleware.CorsMiddleware` has also been added to the `MIDDLEWARE` section.
I created three APIs. One each for registering a new user, for logging in an existing user and for logging out a user. All three of them work perfectly fine as long as no user is logged in. The cookies `csrftoken` and `sessionid` are set just as they should.
Now for my problem:
As soon as a user is logged in all POST APIs - including the three mentioned above - stop to work. I get a simple "403 Forbidden" response. GET APIs seem to work just fine. My research suggest that this is a common error that has something todo with the `csrftoken`, yet I can't seem to get it to work, even after multiple evenings of working on this and trying everything that I could find.
I think I narrowed it down to own specific issue, even though I don't know if this is really is the problem. When I test the APIs not by using them in my React frontend but instead use the frontend that is included with Django to test the APIs they all work just fine, with or without a logged in user.
So I compared both requests in the Network task window of my browser (Firefox) and there is only one difference I could find. Both requests obviously send the `csrftoken` cookie. Both also send the `X-CSRFToken` header, but the value for the header is different for both requests. In the request I send through React the value for the `X-CSRFToken` header is the same as the value of the `csrftoken`. In the request through the Django Frontend the value for the `X-CSRFToken` header is different from the value for the `csrftoken` cookie.
However I cant seem to figure out why that is and if this even is the root of my problem.
As an additional information: I use axios for my HTTP-Requests. For this I included the following lines of code:
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN';
Im at my wits end, no solution I could find on Google or even with Chat-GPTs help seems to solve my problem. So here hoping someone can point out my mistake for me.
</details>
# 答案1
**得分**: 1
尝试使用此配置
```python
DEBUG = True
ALLOWED_HOSTS = ["*"]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders', # <-------- 这个
'myapp',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # <-------- 这个
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'sales_company_app.get_user_instance.RequestMiddleware',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}
CORS_ORIGIN_ALLOW_ALL = True # <-------- 这个
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000", # React (前端 URL) # <-------- 这个
]
CORS_ALLOW_HEADERS = '*' # <-------- 这个
CSRF_TRUSTED_ORIGINS = ["http://192.168.1.155:8000/"] # (API 基础 URL) <-------- 这个(允许 csrf_token)以进行白名单处理
英文:
Try with this config
DEBUG = True
ALLOWED_HOSTS = ["*"]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders', # <-------- this
'myapp',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # <-------- this
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'sales_company_app.get_user_instance.RequestMiddleware',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}
CORS_ORIGIN_ALLOW_ALL = True # <-------- this
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000", # React (FrontEnd Url) # <-------- this
]
CORS_ALLOW_HEADERS = '*' # <-------- this
CSRF_TRUSTED_ORIGINS = ["http://192.168.1.155:8000/"] # (Api Base Url) <-------- this (allow csrf_token) for doing whitelist
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论