I'm trying to do an API request from a react client to a node server using Axios. The request works in MacOS Chrome browsers but does not work on MacOs Safari or iOs Safari and iOS Chrome.
In the same code I make other calls to the same API (different endpoints) and it works with no problems at all in safari and iOs.
I console.log the exception and I am given a very basic Network error with no detail:
My axios request looks like this:
axios.defaults.withCredentials = true;
return axios.get(API_ENDPOINT '/api/auth/user_data/' user_id '/')
.then((response) => {
if (response.data.email) {
localStorage.setItem('user_id', response.data.id);
this.setState({
user_id: response.data.id,
});
return true;
} else {
this.logout();
return false;
}
}).catch(error => {
console.log(error);
this.logout();
return false;
});
My express server cors settings look like this:
const app = express();
var corsOptions = {
credentials: true,
origin: ["https://[production-domain.com]", "http://localhost:3000"]
};
app.use(cors(corsOptions));
If I hit the API from the browser directly I get a successful response:
The error occurs in both my localhost environment (client on localhost:3000 hitting server on localhost:9090) and my production environment (client on production-domain.com:5000 hitting server on production-domain.com:9090)
To me, this rules out problems with the webserver (nginx), which I only use in production.
From my server logs, I can tell that the request is reaching the server, because it triggers logs on my server-side function for the above endpoint. The error is in the response never being sent back to the react client.
My server-side response handler is:
router.get('/user_data/:id', (req, res) => {
console.log("User is authenticated on server: " JSON.stringify(req.isAuthenticated()))
if (!req.user) {
// The user is not logged in, send back an empty object
console.log("THE USER IS NOT LOGGED IN")
res.json({});
} else {
console.log("The supplied user ID is: " req.params.id);
console.log("The stored user ID is: " req.user.id);
// Otherwise send back the user's email and id
if(Number(req.params.id)===Number(req.user.id)){
console.log("USER " req.user.id " IS LOGGED IN")
res.json({
email: req.user.email,
first_name: req.user.first_name,
id: req.user.id,
});
} else {
console.log("Client side user ID does not match. Logging out.")
req.logout();
res.json({});
}
}
});
In my server logs I can see:
User is authenticated on server: true
The supplied user ID is: 35
The stored user ID is: 35
USER 35 IS LOGGED IN
I have tried changing the call from a GET to a POST, but it still does not work.
Very stuck on this, would appreciate any help.
Headers of the failed request are:
Headers of a successful call are:
CodePudding user response:
This issue turned out to be a race condition on the server response (I think).
My axios call was inside of a function in my react client that was being called by both a child class, and on component load, and resulted in my axios request to this endpoint being called twice. I'm not 100% sure why this would result in a response failure, but by making sure it was only called once resolved the issue.