Reputation: 1468
Background and Issues
I have a Flask back-end running in localhost:5000 and a React SPA running on localhost:3000.
I was able to make them talk but when trying to store the token generated from Flask into Browser's cookies 1) response headers does not contain any cookies when doing console.log(response)
after a successful POST from axios
and 2) the cookies are not being set. But when inspecting the network > Login.js header, I could actually see the Set-Cookie
key exists as response's header. I've tried multiple solutions from Google and StackOverflow but no solution seems to work here and I really can't figure out what is going on as the request is being made successfully, and Chrome is allowing third party software to set the cookies. And even I can see the tokens from Network > Login.js header.
Steps
1) Users enters in their username and password and hit login.
2) Axios POST call is made to Flask's back-end.
3) Process the data and generates a couple of tokens and set them into cookies.
4) Browser's cookie are set with few tokens. <- this part is not working.
Code
Flask back-end token generation using flask-jwt-extended
# app_config related to flask-jwt-extended
CORS_HEADERS = "Content-Type"
JWT_TOKEN_LOCATION = ["cookies"]
JWT_COOKIE_SECURE = False
JWT_COOKIE_CSRF_PROTECT = True
# post method from flask-restful for LoginAPI class
def post(self):
email = request.json.get("email")
password = request.json.get("password")
# some processing here.....
payload = {
"email": email
}
access_token = create_access_token(identity=payload)
refresh_token = create_refresh_token(identity=payload)
response = jsonify({"status": True})
set_access_cookies(response, access_token)
set_refresh_cookies(response, refresh_token)
return response
CORS using flask-cors
# in below code, I had some issues with putting wildcard (*) into origin, so I've specified to the React SPA's host and port.
CORS(authentication_blueprint, resources={r"/authentication/*": {"origins": "http://localhost:3000"}},
supports_credentials=True)
React SPA - making a post call using axios
# also tried `axios.defaults.withCredentials = true;` but same result.
export const login = (email, password, cookies) => {
return dispatch => {
const authData = {
email: email,
password: password
};
let url = 'http://127.0.0.1:5000/authentication/login/';
axios.post(url, authData, {withCredentials: true)
.then(
response => {
console.log(response)
})
.catch(err => {
console.log(err)
});
dispatch(authSuccess(email, password));
}
};
Below image is the response from successful post call in axios
.
I'm not sure whether it is normal but response's headers are not showing any of the cookies that I'm setting from the back-end.
And below image is from Network > header for login/
As shown, you can clearly see the token information with Set-Cookie
key. I've also checked that they aren't secure
.
And finally when I check my cookie tab from application > cookies, I do not see anything.
Upvotes: 1
Views: 2857
Reputation: 1468
So the issues were coming from the localhost
.
I have a Flask back-end running in localhost:5000 and a React SPA running on localhost:3000.
From above statement, to be very specific, I was running the back-end on localhost:5000 and running the React SPA on 127.0.0.1:3000.
Once I've changed the 127.0.0.1
to localhost
, it worked like a charm.
And a side note, after playing around with CORS
, I think it will be a lot easier to use Nginx
and proxy_pass
to pass the request coming from React SPA to back-end to avoid using CORS
completely, because if one have to use the CORS
in different environment such as test, staging and etcs, one would have to set up the CORS
at the web server level e.g) Nginx
anyway and it requires slightly different configuration that how I set up for local environment anyway.
Upvotes: 1