I can’t seem to get my cookies to persist on the browser. I want this cookie to persist so then subsequent requests to my API backend will be authenticated.
I have a React frontend being served on port 8080 through a dev server (Vite) and a Flask API backend on port 5000.
My Flask app is using flask-cors and flask-jwt-extended. With flask-jwt-extended
, the settings are mostly default except for these values
JWT_TOKEN_LOCATION="cookies"
JWT_COOKIE_SECURE="false"
JWT_COOKIE_DOMAIN="127.0.0.1"
JWT_CSRF_IN_COOKIES="true"
With flask-cors
I have origins set to 127.0.0.1:8080
With these settings set, React is making a fetch
that looks like this
const response = await fetch(
"http://127.0.0.1:5000/api/authentication/login",
{
method: "POST",
headers: {
credentials: "include",
"Content-Type": "application/json",
},
body: JSON.stringify({email, username}),
}
);
The Flask backend handles the request with this endpoint
def login() -> Response:
email = request.json.get("email", None)
password = request.json.get("password", None)
if email is None or password is None:
return jsonify({"error": "error!"}), 400
tokens = Authentication.login(email=email, password=password)
access_token, refresh_token = (
tokens["access_token"],
tokens["refresh_token"],
)
response = jsonify(access_token=access_token, refresh_token=refresh_token)
set_access_cookies(response=response, encoded_access_token=access_token)
set_refresh_cookies(response=response, encoded_refresh_token=refresh_token)
return response
The response is a 200 with my access_token
and refresh_token
in the response body (expected) and the response headers below.
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://127.0.0.1:8080
Connection: close
Content-Length: 792
Content-Type: application/json
Date: Tue, 02 Jan 2024 21:50:41 GMT
Server: Werkzeug/2.3.8 Python/3.12.0
Set-Cookie:
access_token_cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNzA0MjMyMjQxLCJqdGkiOiJjMTI3MWJiZS0xMDExLTRhODgtOTkxMS01Y2NjMTVjYWVlNTgiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiNzhhM2ZhYmQtODcxMC00ZjlmLWI5MzMtNzcwYWE3NWJhMDQ2IiwibmJmIjoxNzA0MjMyMjQxLCJjc3JmIjoiYjlkZGY3NzEtN2UyMy00ZTdiLTlkOGMtNjJiMjc0N2ZmZjk4IiwiZXhwIjoxNzA0MjM1ODQxfQ.OHAY9puF1pt7rO0IhwTr63Xx-OUoAU-_b9-YtecdQ10; Domain=127.0.0.1; HttpOnly; Path=/
Set-Cookie:
csrf_access_token=b9ddf771-7e23-4e7b-9d8c-62b2747fff98; Domain=127.0.0.1; Path=/
Set-Cookie:
csrf_refresh_token=eded9b74-ed42-4b07-9b9b-f51ee4af923a; Domain=127.0.0.1; Path=/
Set-Cookie:
refresh_token_cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTcwNDIzMjI0MSwianRpIjoiYzEwMTdlMmUtZWVhMy00OTE0LWJiNTUtZWE5NTI3ZWNlYmUzIiwidHlwZSI6InJlZnJlc2giLCJzdWIiOiI3OGEzZmFiZC04NzEwLTRmOWYtYjkzMy03NzBhYTc1YmEwNDYiLCJuYmYiOjE3MDQyMzIyNDEsImNzcmYiOiJlZGVkOWI3NC1lZDQyLTRiMDctOWI5Yi1mNTFlZTRhZjkyM2EiLCJleHAiOjE3MDY4MjQyNDF9.XjfphInWFFULAKbg7aTR_-AqaFgVuiL2yCvZFnaUq1Q; Domain=127.0.0.1; HttpOnly; Path=/