-1

I'm facing a CORS policies issues with Firebase functions even though I think I'm doing the right thing in the backend, I'll show you the code.

const cors = require("cors");
const express = require("express");
const cookieParser = require('cookie-parser');
const app = express();
app.use(
    cors({
        origin: true,
        credentials: true
    }),
    cookieParser(),
);

This is the function I'm trying to call from the frontend:

app.post("/auth/login", (req, res) => login(req, res));

With this body:

const login = async (req, res) => {
  try {
    const user = {
      id: req.body.id,
      password: req.body.password,
    };

    const auth = getAuth();

    const { valid, errors } = validateLoginData(user);

    if (!valid)
      throw { code: "validation-failed", message: errors, status: 400 };

    let data = await signInWithEmailAndPassword(auth, user.id, user.password);
    let token = await data.user.getIdToken();

    console.log("TOKEN: " + token);

    res.cookie("_token", token, { httpOnly: true, maxAge: 3600000 });

    return res.status(202).json({ message: "OK" });
  } catch (err) {
    switch (err.code) {
      case "validation-failed":
        return res.status(err.status).json({ message: err.message });

      case "auth/user-not-found":
      case "auth/wrong-password":
        return res
          .status(401)
          .json({ message: "Wrong credentials, please try again" });

      default:
        return res.status(500).json({ message: err.message });
    }
  }
};

So here's the problem: when I call this from postman it works, when I call this from my browser (Brave) it doesn't work and it tells me this in the console:

Access to XMLHttpRequest at 'https://europe-west1-stormtestfordota.cloudfunctions.net/api/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

I've tried with many fixes that I found online but none has worked, can you help me please?

MarioG8
  • 5,122
  • 4
  • 13
  • 29
Allennick
  • 445
  • 2
  • 10

1 Answers1

0

CORS is a node.js package for providing Express middleware that can be used to enable CORS with various options.

  • Enable all CORS requests
  • Enable CORS for a single route
  • Configuring CORS
  • Configuring CORS with dynamic origin
  • Enable CORS Preflight
  • Enable CORS asynchronously

If you want to use Express and CORS middleware like that, you should try onRequest functions as shown below:

const express = require('express');
const cors = require('cors'); 
const app = express(); // Automatically allow cross-origin requests 
app.use(cors({ origin: true })); // build multiple CRUD interfaces:
app.get('/test2', (req, res) => { //Handle your test2 methods here
return res.send('your response') 
}); // Expose Express API as a single Cloud Function: 
exports.api = functions.https.onRequest(app);
 

Now in this case the CORS middleware you wrote will be running. Your function's URL may look something like - https://us-central1-myapp.cloudfunctions.net/api Then to use the /test2 route it becomes https://us-central1-myapp.cloudfunctions.net/api/test2. CORS shouldn't be an issue anymore here but do note it's an express app now so the parameters in the function are Request, Response instead of data, context.

Also try to follow the steps outlined on https://cloud.google.com/functions/docs/samples/functions-http-cors#functions_http_cors-nodejs and the function will look something like below as in this

exports.hello = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', '*'); 
response.set('Access-Control-Allow-Credentials', 'true'); // vital 
if (request.method === 'OPTIONS') { // Send response to OPTIONS requests
response.set('Access-Control-Allow-Methods', 'GET'); 
response.set('Access-Control-Allow-Headers', 'Content-Type'); 
response.set('Access-Control-Max-Age', '3600'); 
response.status(204).send(''); 
} 
else {
 const params = request.body; 
const html = 'some html'; 
response.send(html)
 } )};

Also have this essential reading on CORS for better understanding of the issue.

Priyashree Bhadra
  • 3,182
  • 6
  • 23