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

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

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

问题

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

  1. from rest_framework.request import Request
  2. from rest_framework.response import Response
  3. from rest_framework.decorators import api_view, permission_classes, authentication_classes
  4. from rest_framework.permissions import IsAuthenticated, AllowAny
  5. from rest_framework.authentication import SessionAuthentication
  6. from core.serializers import UserSerializer, LoginRequestSerializer, iPadSerializer
  7. from core.models import iPad
  8. from rest_framework import status, viewsets, generics
  9. from django.http import JsonResponse
  10. from django.contrib.auth import authenticate, login, logout
  11. @api_view(['POST'])
  12. @permission_classes([AllowAny])
  13. def logout_view(request):
  14. logout(request)
  15. return Response(status=status.HTTP_200_OK)

这是我的React中的handleLogout函数:

  1. const handleLogout = () => {
  2. setLoading(true);
  3. fetch('http://localhost:8000/api/logout', {
  4. credentials: 'include',
  5. method: 'POST',
  6. headers: {
  7. 'Content-Type': 'application/json;charset=utf-8',
  8. 'X-CSRFToken': csrftoken,
  9. },
  10. })
  11. .then((response) => {
  12. if (response.ok) {
  13. setIsLoggedIn(false);
  14. setError(null);
  15. } else {
  16. throw Error(`Something went wrong: code ${response.status}`);
  17. }
  18. })
  19. .catch((error) => {
  20. console.log(error);
  21. setError('Ошибка при выходе');
  22. })
  23. .finally(() => setLoading(false));
  24. };

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

  1. CORS_ALLOW_CREDENTIALS = True
  2. CORS_ALLOWED_ORIGINS = [
  3. 'http://localhost:3000',
  4. 'http://127.0.0.1:3000',
  5. ]
  6. CORS_ALLOW_METHODS = [
  7. "DELETE",
  8. "GET",
  9. "OPTIONS",
  10. "PATCH",
  11. "POST",
  12. "PUT",
  13. ]
  14. CORS_ALLOW_HEADERS = [
  15. "accept",
  16. "accept-encoding",
  17. "authorization",
  18. "content-type",
  19. "dnt",
  20. "origin",
  21. "user-agent",
  22. "x-csrftoken",
  23. "x-requested-with",
  24. ]

我有一个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:

  1. `from rest_framework.request import Request
  2. from rest_framework.response import Response
  3. from rest_framework.decorators import api_view, permission_classes, authentication_classes
  4. from rest_framework.permissions import IsAuthenticated, AllowAny
  5. from rest_framework.authentication import SessionAuthentication
  6. from core.serializers import UserSerializer, LoginRequestSerializer, iPadSerializer
  7. from core.models import iPad
  8. from rest_framework import status, viewsets, generics
  9. from django.http import JsonResponse
  10. from django.contrib.auth import authenticate, login, logout
  11. @api_view([&#39;POST&#39;])
  12. @permission_classes([AllowAny])
  13. def logout_view(request):
  14. logout(request)
  15. return Response(status=status.HTTP_200_OK)`

And that's how my react handleLogout looks:

  1. const handleLogout = () =&gt; {
  2. setLoading(true);
  3. fetch(&#39;http://localhost:8000/api/logout&#39;, {
  4. credentials: &#39;include&#39;,
  5. method: &#39;POST&#39;,
  6. headers: {
  7. &#39;Content-Type&#39;: &#39;application/json;charset=utf-8&#39;,
  8. &#39;X-CSRFToken&#39;: csrftoken,
  9. },
  10. })
  11. .then((response) =&gt; {
  12. if (response.ok) {
  13. setIsLoggedIn(false);
  14. setError(null);
  15. } else {
  16. throw Error(`Something went wrong: code ${response.status}`);
  17. }
  18. })
  19. .catch((error) =&gt; {
  20. console.log(error);
  21. setError(&#39;Ошибка при выходе&#39;);
  22. })
  23. .finally(() =&gt; setLoading(false));
  24. };

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:

  1. CORS_ALLOW_CREDENTIALS = True
  2. CORS_ALLOWED_ORIGINS = [
  3. &#39;http://localhost:3000&#39;,
  4. &#39;http://127.0.0.1:3000&#39;,
  5. ]
  6. CORS_ALLOW_METHODS = [
  7. &quot;DELETE&quot;,
  8. &quot;GET&quot;,
  9. &quot;OPTIONS&quot;,
  10. &quot;PATCH&quot;,
  11. &quot;POST&quot;,
  12. &quot;PUT&quot;,
  13. ]
  14. CORS_ALLOW_HEADERS = [
  15. &quot;accept&quot;,
  16. &quot;accept-encoding&quot;,
  17. &quot;authorization&quot;,
  18. &quot;content-type&quot;,
  19. &quot;dnt&quot;,
  20. &quot;origin&quot;,
  21. &quot;user-agent&quot;,
  22. &quot;x-csrftoken&quot;,
  23. &quot;x-requested-with&quot;,
  24. ]

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']

更改为:

  1. @api_view(['POST'])

改为:

  1. @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 :

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

to :

  1. @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:

确定