{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.