React и Django: CSRF Token не установлен на продакшене, и особенно для метода create

на разработке, куки csrf устанавливались нормально, если они не были доступны на вкладке приложения в dev tool, однако на продакшене, когда я пытаюсь создать новый пост, он говорит мне " CSRF Failed: CSRF token from the 'X-Csrftoken' HTTP header has incorrect length.". однако, интрига здесь в том, что при других запросах к посту, например, когда вы входите в систему или регистрируетесь, все работает отлично и прекрасно, так что я решил, что это проблема с методом create в django (НО с логином, несмотря на то, что логин работает отлично, и что я вхожу, используя аутентификацию на основе сессии, похоже, что session_id и csrf невидимы на вкладке приложения?

enter image description here

Я предполагаю, что это потому, что сайт находится на производстве, и по соображениям безопасности он не может показывать session_id там.

Однако, когда я пытаюсь заглянуть на вкладку network после того, как я попытался создать сообщение и потерпел неудачу, это выглядит так, как будто x-csrftoken это undefined

enter image description here

но есть еще один ключ cookie, который включает в себя и csrftoken и session_id

enter image description here

обратите внимание, что это происходит только на продакшене, я никогда не сталкивался с такой проблемой на сервере разработки, и посмотрите на код settings.py после кода просмотра для большего прояснения (я добавил https://somedomain.com для домена, которому нужен разрешенный токен csrf)

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)
    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.")

Теперь в frontend:

let handleSubmit = (e)=>{
        e.preventDefault()
        console.log(Cookies.get('csrftoken'))
        axios.post('https://somedomain.com/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})

    },[])

Код

settings.py:

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','https://somedomain.com/']

SECURE_SSL_REDIRECT = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 60

CUSTOM_HEADERS = (
    'Access-Control-Allow-Origin',
    'Token',
    'User-Type'
)
CORS_ALLOW_HEADERS = default_headers + CUSTOM_HEADERS
CSRF_COOKIE_SAMESITE = 'none'

Я забыл ответить на этот вопрос, в основном фронтенд обслуживается на другом поддомене, поэтому правило cookie samesite должно быть установлено на None, в settings.py: измените CSRF_COOKIE_SAMESITE = 'Strict' на CSRF_COOKIE_SAMESITE = 'None'

также, если вы используете аутентификацию на основе сессий (которая по умолчанию требует токен csrf для почтовых запросов, читайте документацию здесь), не забудьте добавить: SESSION_COOKIE_SAMESITE = 'None' в settings.py

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