FastAPI is not returning cookies to React frontend
FastAPI не возвращает файлы cookie во внешний интерфейс React
Почему FastAPI не возвращает файлы cookie в мой внешний интерфейс, который является приложением React?
Вот мой код:
@router.post("/login") defuser_login(response: Response,username :str = Form(),password :str = Form(),db: Session = Depends(get_db)): user = db.query(models.User).filter(models.User.mobile_number==username).first() ifnot user: raise HTTPException(400, detail='wrong phone number or password') ifnot verify_password(password, user.password): raise HTTPException(400, detail='wrong phone number or password')
access_token = create_access_token(data={"sub": user.mobile_number}) response.set_cookie(key="fakesession", value="fake-cookie-session-value") #here I am set cookie return {"status":"success"}
Когда я захожу в систему из автодокументов Swagger UI, я вижу файл cookie в заголовках ответов с помощью DevTools в браузере Chrome. Однако, когда я захожу в систему из своего приложения React, файл cookie не возвращается. Я использую axios для отправки запроса следующим образом:
await axios.post(login_url, formdata)
Переведено автоматически
Ответ 1
Сначала создайте файл cookie, как показано в примере ниже, и убедитесь, что при выполнении запроса Axios POST не возвращается ошибка, и что вы получаете 'status': 'success' ответ с 200 кодом состояния. Возможно, вы также захотите ознакомиться с этим ответом, в котором также объясняется, как использовать флаги max_age и expires.
Во—вторых, как вы упомянули, вы используете React во внешнем интерфейсе — который должен прослушивать порт, отличный от того, который используется для серверной части FastAPI, что означает, что вы выполняете запросы CORS - вам нужно установить для withCredentials свойства значение true (по умолчанию оно установлено в false), чтобы разрешить получение / отправку учетных данных, таких как файлы cookie и заголовки HTTP-аутентификации, от / к другим источникам. Два сервера с одинаковым доменом и протоколом, но с разными портами, например, http://localhost:8000 и http://localhost:3000 считаются разными источниками (см. Документацию FastAPI по CORS и этот ответ, в котором подробно описаны файлы cookie в целом, а также решения для настройки междоменных файлов cookie, которые в вашем случае на самом деле вам не нужны, поскольку домен одинаков как для серверной части, так и для внешнего интерфейса, и, следовательно, установка файлов cookie в обычном режиме будет работать просто отлично).
Обратите внимание, что если вы обращаетесь к интерфейсу React, набирая http://localhost:3000 в адресной строке вашего браузера, то ваши запросы Axios к серверной части FastAPI должны использовать localhost домен в URL, например, axios.post('http://localhost:8000',..., а неaxios.post('http://127.0.0.1:8000',..., поскольку localhost и 127.0.0.1 - это два разных домена, и, следовательно, файл cookie в противном случае не был бы создан для localhost домена, как это было бы сделано для 127.0.0.1, т. Е. домена, используемого в axios запросе (и тогда это было бы случаем перекрестного доступа). -файлы cookie домена, как описано в связанном ответе выше, который, опять же, в вашем случае не понадобился бы).
Таким образом, чтобы принять файлы cookie, отправленные сервером, вам необходимо использовать withCredentials: true в вашем запросе Axios; в противном случае файлы cookie будут проигнорированы в ответе (что является поведением по умолчанию, когда withCredentials установлено значение false; следовательно, различные домены не могут устанавливать файлы cookie для своего собственного домена). То же самое withCredentials: true свойство должно включаться в каждый последующий запрос к вашему API, если вы хотите, чтобы файл cookie отправлялся на сервер, чтобы пользователь мог пройти аутентификацию и получить доступ к защищенным маршрутам.
Следовательно, запрос Axios, включающий учетные данные, должен выглядеть следующим образом:
Эквивалент в fetch() запросе (т. Е. С использованием Fetch API) равен credentials: 'include'. Значение по умолчанию для credentials равно same-origin. Использование credentials: 'include' приведет к тому, что браузер будет включать учетные данные как в запросы одного источника, так и в запросы разных источников, а также установит любые файлы cookie, отправленные обратно в ответах разных источников. Например:
Поскольку вы выполняете запрос из разных источников, для того чтобы любой из вышеперечисленных способов сработал, вам нужно будет явно указать разрешенные источники, как описано в этом ответе (за кулисами, то есть установить Access-Control-Allow-Origin заголовок ответа). Например:
Using the * wildcard instead would mean that all origins are allowed; however, that would also only allow certain types of communication, excluding everything that involves credentials, such as cookies, authorization headers, etc—hence, you should not use the * wildcard.