{detail: 'CSRF Failed: CSRF токен отсутствует.'} Django и React

даже если csrf предоставлен, он просто не распознает его на стороне frontend (обратите внимание, что он отлично работает на backend хосте, но не на frontend)

views.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'),
]

теперь в frontend:

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})

    },[])

в консоль dev выводится csrf

есть идеи?

После повторного просмотра вашего кода, я думаю, что понял проблему. Ваш запрос с 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]])

Если совпадают один за другим.

url - 'http://127.0.0.1:8000/posts/'

data - post (я предполагаю, что это переменная, в которой сохраняются данные, я предлагаю вам переименовать ее)

config - {withCredentials:true}

Пока я не понял, ваш cookie отправляется (из-за withCredentials:true), но ваш заголовок - нет. Они игнорируются axios.

Таким образом, вы должны поместить всю конфигурацию в один объект. Например, используя переменную:

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

Если хотите, можете добавить xsrfHeaderName: 'X-CSRFToken' и xsrfCookieName: 'csrftoken' к объекту. Проверьте Request Config.

И запрос.

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

Теперь в запрос должны быть отправлены эти данные. Вы можете проверить это в DevTools > Network.

Вернуться на верх