Django не создает куки сессии в межсайтовом json-запросе

Я хочу сделать межсайтовый JavaScript вызов из стороннего домена (в данном случае с моего рабочего стола/сервера localhost) на мой удаленный сервер Django, расположенный на my_domain.com/, и вызвать REST WS, открытый на my_domain.com/msg/my_service с использованием session/cookies для хранения состояния сессии.

Но когда я вызываю этот сервис (размещенный на удаленном Django сервере) из браузера моего рабочего стола или с локалхостового Django сервера (JS находится в index.html), Django не создает куки сессии и на удаленном сервере не хранится состояние сессии. Но когда я вызываю этот сервис из Postman или из того же localhost JS на localhost экземпляр того же сервиса Django, он работает и сессия создается.

Мой JS скрипт в index.html, который делает вызов WS send_message:

                fetch('http://my_domain.com/ws/my_service', {
                            method:"POST",
                                credentials: 'include',
                            body:JSON.stringify(data)
                            })
                            .then(res => res.json())
                            .then(json => {
                                            showResponse(json.message);
                            })

Когда я запускаю этот скрипт из браузера на рабочем столе или с сервера localhost, он работает правильно с параметрами cookies и сессий.

Django представление реализации my_service

@csrf_exempt
def my_service(request):
    if request.method == "POST":

        message_bstream= request.body
    
        request.session.set_expiry(0)
        
        message= json.loads(message_bstream)
    
        out,sta=state_machine_response(message["message"],int(request.session["state"]))
     
        request.session["state"] =sta
        respo={"message":out}
    
        response = HttpResponse(json.dumps(respo), content_type="application/json")
        response.set_cookie(key='name', value='my_value', samesite='None', secure=True)
        #return JsonResponse(respo, safe=False, status=200)
        return response
    else:
        return HttpResponseNotFound ("Sorry this methode is not allowed")

Или я пытаюсь сгенерировать ответ типа

return JsonResponse(respo, safe=False, status=200)

Мой settings.py

    INSTALLED_APPS = [
  ...
    'corsheaders',
]

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
    'http://localhost:8000', 
)

 CORS_ALLOWED_ORIGINS = [
    'http://localhost:8000',
]

CSRF_TRUSTED_ORIGINS = [
    'http://localhost:8000',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CSRF_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'None'

Пожалуйста, у вас есть какие-нибудь идеи?

Вы не сможете сохранить куки от стороннего вызова API, если не используете SameSite=None с опцией Secure в заголовке Set-Cookie. Вы можете добиться этого для sessionid и CSRF cookie с помощью следующих настроек:

CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'None'

В этом случае вы должны использовать схему протокола HTTPS.

Другим решением может быть использование прокси, что полезно в среде разработки на локальном хосте. Вот пример использования vue.js на файле vue.config.js:

const { defineConfig } = require('@vue/cli-service')

if (process.env.NODE_ENV == "development"){
  module.exports = defineConfig({
    transpileDependencies: true,
    devServer: {
      proxy: {
        "^/api/": {
          target: process.env.VUE_APP_BASE_URL,
          changeOrigin: true,
          logLevel: "debug",
          pathRewrite: { "^/api": "/api" }
        }
      }
    },
  })
}

Полезный документ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#samesitenone_requires_secure

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