Django Rest Framework: 登录用户后,所有的POST API仅返回“禁止访问”。

huangapple go评论72阅读模式
英文:

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中包含了corsheadersCORS_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,一个用于注册新用户,一个用于登录现有用户,另一个用于注销用户。只要没有用户登录,它们三者都能正常工作。csrftokensessionid这两个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 &quot;403 Forbidden&quot;.

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 &quot;403 Forbidden&quot; 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&#39;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&#39;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',  # &lt;-------- 这个
    'myapp',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',  # &lt;-------- 这个
    '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  # &lt;-------- 这个
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",    # React (前端 URL) # &lt;-------- 这个
]

CORS_ALLOW_HEADERS = '*'  # &lt;-------- 这个
CSRF_TRUSTED_ORIGINS = ["http://192.168.1.155:8000/"]  # (API 基础 URL) &lt;-------- 这个(允许 csrf_token)以进行白名单处理
英文:

Try with this config

DEBUG = True

ALLOWED_HOSTS = [&quot;*&quot;]


# Application definition

INSTALLED_APPS = [
    &#39;django.contrib.admin&#39;,
    &#39;django.contrib.auth&#39;,
    &#39;django.contrib.contenttypes&#39;,
    &#39;django.contrib.sessions&#39;,
    &#39;django.contrib.messages&#39;,
    &#39;django.contrib.staticfiles&#39;,
    &#39;rest_framework&#39;,
    &#39;corsheaders&#39;, # &lt;-------- this
    &#39;myapp&#39;,
]

MIDDLEWARE = [
    &#39;django.middleware.security.SecurityMiddleware&#39;,
    &#39;django.contrib.sessions.middleware.SessionMiddleware&#39;,
    &#39;corsheaders.middleware.CorsMiddleware&#39;, # &lt;-------- this
    &#39;django.middleware.common.CommonMiddleware&#39;,
    &#39;django.middleware.csrf.CsrfViewMiddleware&#39;,
    &#39;django.contrib.auth.middleware.AuthenticationMiddleware&#39;,
    &#39;django.contrib.messages.middleware.MessageMiddleware&#39;,
    &#39;django.middleware.clickjacking.XFrameOptionsMiddleware&#39;,
    &#39;sales_company_app.get_user_instance.RequestMiddleware&#39;,
]



REST_FRAMEWORK = {
    &#39;DEFAULT_AUTHENTICATION_CLASSES&#39;: (
        &#39;rest_framework.authentication.TokenAuthentication&#39;,
    ),
}


CORS_ORIGIN_ALLOW_ALL = True # &lt;-------- this
CORS_ALLOWED_ORIGINS = [
    &quot;http://localhost:3000&quot;,    # React (FrontEnd Url) # &lt;-------- this
]

CORS_ALLOW_HEADERS = &#39;*&#39; # &lt;-------- this
CSRF_TRUSTED_ORIGINS = [&quot;http://192.168.1.155:8000/&quot;] # (Api Base Url) &lt;-------- this (allow csrf_token) for doing whitelist 

huangapple
  • 本文由 发表于 2023年6月8日 05:50:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76427316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定