Getting CORS error even when using cors library

68 views Asked by At

I'm getting a cors error when trying to host my project on render using expressjs and react. everything works fine when using local host, but changing the urls to match the site throws 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.

I've tried manually adding the header in the request as well as using fetch instead of axios incase of a default configuration issue, but I still get some type 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");
      }
    }
  }

I've also tried adding additional options in the cors configuration on the backend and manually setting the header in the '/login' method using res.set().. both of which still display 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' });
  }
});

Additionally, I've reached out to render and they said their site in no way affects cors so its definitely a problem with the code. I've tried hosting it on azure to confirm this and got the same cors error.

1

There are 1 answers

6
None On

The CORS header needs to be in the response, not the request. The goal of CORS is for the server to decide which origin domains have access to server side data (for CORS compliant browsers).

When https://book-listing-app-api.onrender.com/login receives a request from origin https://book-listing-app.onrender.com, CORS applies.

The server response needs to include an Access-Control-Allow-Origin: https://book-listing-app.onrender.com header authorizing cross origin requests from the domain book-listing-app.onrender.com.

Other Access-Control-* headers may be needed depending on the goal of the cross origin request.

Access-Control-Allow-Methods: <HTTP METHOD> limits the CORS request to a specific HTTP Method. GET, PUT, POST, DELETE, HEAD are the default methods.

Access-Control-Allow-Credentials: <boolean> controls whether cookies are honored or not.

Browsers are increasingly more strict about CORS rules. The exact protocol://domain:port should be returned in the CORS Access-Control-Allow-Origin header from https://book-listing-app-api.onrender.com/login for the most comprehensive security.