Как передать куки с Flask-сервера на ReactJS-фронт?

Рейтинг: 0Ответов: 2Опубликовано: 05.04.2023

Вот роут на Flask:

...
@app.route('/login', methods=['POST'])
def login_user():
    data = json.loads(request.data)
    email, password = data['email'], data['password']
    user = my_db.get_user_by_email(email)
    if not user:
        return jsonify({
            'error': 'User do not exists'
        })
    if check_password_hash(user.password, password):
        session[str(user.id)] = uuid4().hex
        res = make_response({
            'id': user.id,
            'email': user.email
        })
        res.set_cookie(key='uid', value=str(user.id))
        return res
    return jsonify({
        'error': 'Wrong password or email'
    })

Принимается запрос, обрабатывается. Далее через ф-ию make_response() создаю ответ, к нему прикрепляю куки через make_response().set_cookie(), создаю сессию на сервере через объект session. Когда я логинюсь через JS:

const login = async (body) => {
        let res = await fetch('http://127.0.0.1:5000/login', {body: 
        JSON.stringify(body), method: "POST"})
        return res.json()
    }

а затем проверяю вкладку Application в DevTools или пробегаюсь циклом по хэдерам ответа: ни там, ни там нет кук, нет даже хэдера Set-Cookie. Хотя они написаны тут: Вкладка Networks in DevTools

и тут они тоже есть: Response cookies

А такой код:

const login = async (body) => {
        let res = await fetch('http://127.0.0.1:5000/login', {body: 
        JSON.stringify(body), method: "POST"})
        res.headers.forEach(elememt => {
                console.log(elememt)
            });
        return res.json()
    }

Выводит только:

27
application/json

Интересно, что, если проворачивать такую же тему с функцией set_cookies() на шаблонитизаторе, то куки прикрепляются и к ним возможно обращение, когда на сервер поступает запрос извне. Как правильно создавать куки на сервере и прикреплять их к фронту? Используется ли вообще такое, или больше в обиходе какой-то иной способ сохранения инфы на клиенте?

Ответы

▲ 0Принят

Короче говоря, проблема была с CORS. В функции fetch в options добавил поле

credentials: "include"

Во Flask изменил следующее:

CORS(app, supports_credentials=True)
...
...
...
response.set_cookie('uid', str(user.id), samesite='None', secure=True)

При этом прикрепляется эта кука, но кука сессии - нет. Проблема, как я понял, в том, что на локалхосте нет https.

▲ 1

В спецификации явно прописан запрет на чтение заголовков Set-Cookie. Так что из JS вы их никак не получите.

https://fetch.spec.whatwg.org/#forbidden-response-header-name

https://fetch.spec.whatwg.org/#concept-filtered-response

И таки непонятно зачем вы их хотите прочитать?

P.S. И вообще тестровать работу cookie на запросах по IP и на домене localhost плохая идея. Это слишком специальные домены со своими приколами и исключениями из стандартного поведения.