簡體   English   中英

{detail: 'CSRF Failed: CSRF token missing.'} Django 和 React

[英]{detail: 'CSRF Failed: CSRF token missing.'} Django and React

即使提供了 csrf,它在前端根本無法識別它(注意它在后端完美運行,但不是前端)

視圖.py:

class CheckAuthenticated(views.APIView):
    def get(self, request):
        if request.user.is_authenticated:
            return Response("Authenticated")
        else:
            return Response("Not Authenticated",status=401)
    
class PostView(viewsets.ModelViewSet):
    serializer_class = serializer.PostSerializer

    def get_queryset(self):
        queryset = models.Post.objects.all()
        return queryset
    
    @method_decorator(ensure_csrf_cookie,csrf_protect)
    def create(self,request):
        authentication_classes = [SessionAuthentication]
        permissions_classes = [IsAuthenticated]
        post = serializer.PostSerializer(data=request.data)
        if post.is_valid():
            title = post.data['title']
  
            description = post.data['description']
    
            models.Post.objects.create(title=title,description=description,user=User.objects.first())
            return Response("post created successfully.")
        return Response("post creation failed.")

我還有一個接收 csrf 令牌的資源:

 
class GetCSRFToken(views.APIView):
    permission_classes = [AllowAny, ]

    
    @method_decorator(ensure_csrf_cookie)
    def get(self, request, format=None):
        return Response("Success")

在 urls.py 中:

  urlpatterns = [
   path('csrf/',views.GetCSRFToken.as_view(),name='csrf'),
   path('isauthenticated/',views.CheckAuthenticated.as_view(),name='authenticated'),
]

現在在前端:

let handleSubmit = (e)=>{
        e.preventDefault()
        console.log(Cookies.get('csrftoken'))
        axios.post('http://127.0.0.1:8000/posts/',post,{withCredentials:true},{headers:{'X-CSRFToken':Cookies.get('csrftoken')}}).then((res)=>{
            console.log(res.data)
        }).catch((e)=>{
            console.log(e.response.data)
            console.log(Cookies.get('csrftoken'))
        })
    }
    useEffect(()=>{
        axios.get('http://127.0.0.1:8000/posts/').then((res)=>{
            setPostList(res.data)
        })
        axios.get('http://127.0.0.1:8000/csrf/',{headers:{Authorization:null},withCredentials:true})

    },[])

csrf 正在開發控制台中打印

任何想法?

編輯我的 csrf 設置,因為有人在評論中要求:

ALLOWED_HOSTS = ['*']
ACCESS_CONTROL_ALLOW_ORIGIN = '*'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
ACCESS_CONTROL_ALLOW_CREDENTIALS = True
ACCESS_CONTROL_ALLOW_METHODS = '*'
ACCESS_CONTROL_ALLOW_HEADERS = '*'

'''
SESSION_COOKIE_SECURE = True

CSRF_COOKIE_PATH = '/'
'''
CSRF_COOKIE_SAMESITE = 'Strict'  




CSRF_TRUSTED_ORIGINS = [ "http://127.0.0.1:3000",'http://127.0.0.1:8000']

編輯:我發現在 settings.py 我在 drf 中的身份驗證有問題:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
    ]
}

這就是導致問題的原因,但是如果我嘗試更改為BasicAuthentication之類的,即使我登錄了,我也會未經授權

我想這是解決方案的一半,也就是找到問題所在。

再次檢查您的代碼后,我想我找到了問題所在。 您對 axios 的要求不正確。

axios.post(
            'http://127.0.0.1:8000/posts/',
            post,
            {withCredentials:true},
            {headers:{
                'X-CSRFToken':Cookies.get('csrftoken')}}
).then((res)=>{
            ...

現在檢查Axios API

axios.post(url[, data[, config]])

如果一一匹配。

網址 - 'http://127.0.0.1:8000/posts/'

data - post(我猜這是保存數據的變量,我建議你重命名它)

配置 - {withCredentials:true}

直到我了解您的 cookie 已發送(由於withCredentials:true ),但您的標頭未發送。 axios 會忽略它們。

因此,您必須將所有配置放在同一個對象中。 例如使用變量:

const postRequestConf = {
    withCredentials: true,
    headers: {
        'X-CSRFToken': Cookies.get('csrftoken')
    }
}

如果需要,可以將xsrfHeaderName: 'X-CSRFToken'xsrfCookieName: 'csrftoken'添加到對象中。 檢查請求配置

和請求。

axios.post(
           'http://127.0.0.1:8000/posts/',
           renamedVariable,
           postRequestConf
).then( res => {...})...

現在,請求必須發送此數據。 您可以在 DevTools > Network 中驗證它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM