even though csrf is provided, it just does not recognize it at all in frontend side (note it works perfect on backend, but not 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.")
i have also a resource that receive csrf token:
class GetCSRFToken(views.APIView):
permission_classes = [AllowAny, ]
@method_decorator(ensure_csrf_cookie)
def get(self, request, format=None):
return Response("Success")
in urls.py:
urlpatterns = [
path('csrf/',views.GetCSRFToken.as_view(),name='csrf'),
path('isauthenticated/',views.CheckAuthenticated.as_view(),name='authenticated'),
]
now in 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})
},[])
the csrf is being printed in the dev console
any idea?
EDIT my csrf settings, since someone requested in the comments:
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']
EDIT : I figured out that in settings.py i have a problem with authentication in drf:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
]
}
this is what causing the problem, but if i tried to change to like BasicAuthentication i would be unauthorized even if i logged in
I guess this is half the solution, which is finding the problem.
createmethod, this one only have to be decorated withcsrf_protect, because with@method_decorator(ensure_csrf_cookie,csrf_protect)you are protecting the view (POST mehod) with CSRF and at the same time it forces to send a new token CSRF.