Encountering a CORS error while attempting to deploy my project on render using expressjs and react. The project functions smoothly on localhost, but changing the URLs to match the website results in this error:
Access to XMLHttpRequest at 'https://book-listing-app-api.onrender.com/login' from origin 'https://book-listing-app.onrender.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Despite manually adding the header in the request and trying fetch instead of axios to rule out default configuration issues, I still face some form of blocked-by-CORS error.
function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [redirect, setRedirect] = useState(false);
async function loginUser(e) {
e.preventDefault();
try {
const response = await axios.post(
`${process.env.REACT_APP_SERVER_URL}/login`,
{
username: username,
password: password,
},
{
withCredentials: true,
// headers: {
// "Access-Control-Allow-Origin": "https://book-listing-app.onrender.com",
// },
}
);
// const response = await fetch(
// `${process.env.REACT_APP_SERVER_URL}/login`,
// {
// method: "POST",
// headers: { "Content-Type": "application/json"},
// body: JSON.stringify({
// username: username,
// password: password,
// }),
// credentials: 'include'
// }
// );
if (response.status === 200) {
setRedirect(true);
}
} catch (err) {
if (err.response.status === 401) {
alert("Invalid username or password");
}
}
}
Have also attempted to add more options in the cors configuration on the backend and setting the header manually in the '/login' method using res.set().. both of which lead to a blocked-by-CORS error.
const cors = require('cors');
app.use(
cors({
credentials: true,
origin: 'https://book-listing-app.onrender.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['content-type', 'Authorization', 'token'],
}),
);
// app.options('/login', cors());
app.post('/login', (req, res) => {
try {
const { username, password } = req.body;
console.log(username, password);
if (!username || !password) {
return res
.status(400)
.json({ error: 'Username and password are required' });
}
const q = 'SELECT * FROM book_store.users WHERE username = ?';
db.query(q, [username], (err, data) => {
console.log('Query Error:', err);
console.log('Query Result:', data);
if (err) {
console.log(data);
}
if (data.length === 1) {
const { id, username, password: storedPass } = data[0];
console.log('Entered password:', password);
console.log('Stored hashed password:', storedPass);
const passMatch = bcrypt.compareSync(password, storedPass);
if (passMatch) {
jwt.sign(
{
id,
username,
},
secret,
{
expiresIn: '1h',
},
(err, token) => {
if (err) {
console.log(err);
} else {
// res.set('Access-Control-Allow-Origin', 'https://book-listing-app.onrender.com');
res.cookie('token', token).json({ id, username });
}
},
);
}
} else {
res.status(401).json({ error: 'Invalid username or password' });
}
});
} catch (err) {
console.error(err);
return res.status(500).json({ message: 'Internal server error' });
}
});
Moreover, contacted render and they clarified that their site does not affect CORS in any way, revealing that the issue lies within the code. To confirm this, tried hosting it on azure and encountered the same CORS error.