Django后端 + React前端在注销功能上出现403禁止,尽管已更改权限为AllowAny

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

Django back + react front 403 forbidden on logout function although changed permissions to AllowAny

问题

尝试使用Django REST API + React创建一个简单的Web服务。在获取API时,我使用了CORS和绝对路径,同时我还使用了会话认证。除了注销功能之外,一切都运行正常。以下是我的Django views.py文件中的注销函数:

from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.authentication import SessionAuthentication
from core.serializers import UserSerializer, LoginRequestSerializer, iPadSerializer
from core.models import iPad
from rest_framework import status, viewsets, generics
from django.http import JsonResponse
from django.contrib.auth import authenticate, login, logout

@api_view(['POST'])
@permission_classes([AllowAny])
def logout_view(request):
    logout(request)
    return Response(status=status.HTTP_200_OK)

这是我的React中的handleLogout函数:

const handleLogout = () => {
    setLoading(true);
    fetch('http://localhost:8000/api/logout', {
        credentials: 'include',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json;charset=utf-8',
            'X-CSRFToken': csrftoken,
        },
    })
    .then((response) => {
        if (response.ok) {
            setIsLoggedIn(false);
            setError(null);
        } else {
            throw Error(`Something went wrong: code ${response.status}`);
        }
    })
    .catch((error) => {
        console.log(error);
        setError('Ошибка при выходе');
    })
    .finally(() => setLoading(false));
};

我认为问题可能出在我的CORS设置上,但是奇怪的是,其他的fetch请求都正常工作。这是我的CORS设置,但它仍然不起作用:

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOWED_ORIGINS = [
    'http://localhost:3000',
    'http://127.0.0.1:3000',
]

CORS_ALLOW_METHODS = [
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
]
CORS_ALLOW_HEADERS = [
    "accept",
    "accept-encoding",
    "authorization",
    "content-type",
    "dnt",
    "origin",
    "user-agent",
    "x-csrftoken",
    "x-requested-with",
]

我有一个handleLogin函数,它在React端的操作方式完全相同,而且它运行得非常顺畅。另外,如果我将代理更改为127.0.0.1:8000并停止使用绝对URL(使用/api/logout而不是http:...),它也可以正常工作。因此,我仍然认为问题出在我的CORS设置上。对不起我的英文不太好,希望这可以帮助你解决问题。<3

英文:

Trying to do a simple web service using django rest api + react. I'm using CORS and absolute path when fetching API. Also i'm using session auth. Everything works fine except my logout function. That's how it looks django views.py:

`from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.authentication import SessionAuthentication
from core.serializers import UserSerializer, LoginRequestSerializer, iPadSerializer
from core.models import iPad
from rest_framework import status, viewsets, generics
from django.http import JsonResponse
from django.contrib.auth import authenticate, login, logout

@api_view([&#39;POST&#39;])
@permission_classes([AllowAny])
def logout_view(request):
    logout(request)
    return Response(status=status.HTTP_200_OK)`

And that's how my react handleLogout looks:

const handleLogout = () =&gt; {
        setLoading(true);
        fetch(&#39;http://localhost:8000/api/logout&#39;, {
            credentials: &#39;include&#39;,
            method: &#39;POST&#39;,
            headers: {
                &#39;Content-Type&#39;: &#39;application/json;charset=utf-8&#39;,
                &#39;X-CSRFToken&#39;: csrftoken,
            },
        })
            .then((response) =&gt; {
                if (response.ok) {
                    setIsLoggedIn(false);
                    setError(null);
                } else {
                    throw Error(`Something went wrong: code ${response.status}`);
                }
            })
            .catch((error) =&gt; {
                console.log(error);
                setError(&#39;Ошибка при выходе&#39;);
            })
            .finally(() =&gt; setLoading(false));
    };

I thought that problem is my CORS settings, bul strangely every other fetch works fine. That's my CORS settings and it's still don't work:

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOWED_ORIGINS = [
    &#39;http://localhost:3000&#39;,
    &#39;http://127.0.0.1:3000&#39;,
]

CORS_ALLOW_METHODS = [
    &quot;DELETE&quot;,
    &quot;GET&quot;,
    &quot;OPTIONS&quot;,
    &quot;PATCH&quot;,
    &quot;POST&quot;,
    &quot;PUT&quot;,
]
CORS_ALLOW_HEADERS = [
    &quot;accept&quot;,
    &quot;accept-encoding&quot;,
    &quot;authorization&quot;,
    &quot;content-type&quot;,
    &quot;dnt&quot;,
    &quot;origin&quot;,
    &quot;user-agent&quot;,
    &quot;x-csrftoken&quot;,
    &quot;x-requested-with&quot;,
]

I have handleLogin which works exactly the same on react side and it works flawlessly. Also if i change my proxy to 127.0.0.1:8000 and stop using absolute urls (/api/logout instead of http:...) it works just fine, so i still think that problem is my CORS.Sry for my poor english <3

答案1

得分: 1

当您注销http_method_name中的@api_view装饰器是['GET']

更改为:

@api_view(['POST'])

改为:

@api_view(["GET"])

并且在logout_view函数中,您需要删除用户的令牌,以便他不再被验证,类似于:request.user.auth_token.delete()

英文:

When you log out the http_method_name in the @api_view decorator is [&#39;GET&#39;]

change :

@api_view([&#39;POST&#39;])

to :

@api_view([&quot;GET&quot;])

and in the logout_view function, you have to delete the Token for the user so he will no longer be authenticated . something like : request.user.auth_token.delete()

huangapple
  • 本文由 发表于 2023年7月3日 07:39:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76601162.html
匿名

发表评论

匿名网友

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

确定