简体   繁体   中英

How to solve CORS error when using with React, Axios, Express?

I am making simple twitter login using passport js, but when calling twitter route, I get CORS error.

server.js

const express = require("express");
const session = require("express-session");
const dotenv = require("dotenv");
const userLoginRoutes = require("./routes/userLoginRoute");
const cors = require("cors");
const app = express();

app.use(cors());
app.use(function (req, res, next) {
  res.header(
    "Access-Control-Allow-Origin",
    "*"
  ); // update to match the domain you will make the request from
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});
app.get("/api/auth/twitter", passport.authenticate("twitter"));

action dispatching here

import {
  USER__LOGIN,
  USER__LOGIN__FAILURE,
  USER__LOGIN__SUCCESS,
} from "../constants/loginconstants";

const axios = require("axios");

// login action
export const userLoginAction = () => async (dispatch) => {
  try {
    dispatch({
      type: USER__LOGIN,
    });
    const config = {
      header: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin" : "*"
      },
    };
    const { data } = await axios.get(`/api/auth/twitter`, config);
    dispatch({
      type: USER__LOGIN__SUCCESS,
      payload: data,
    });
  } catch (error) {
    dispatch({
      type: USER__LOGIN__FAILURE,
      payload:
        error.response && error.response.data.message
          ? error.response.data.message
          : error.message,
    });
  }
};

in package.json in client,

  "proxy": "http://127.0.0.1:3001",

Also I cannot see Access-Control-Allow-Origin in the.network tab, see here, 在此处输入图像描述

Is there anything wrong while setting the Access-Control-Allow-Origin ?

I cannot figure out, where am I getting wrong. I have used cors, and even manually set the origin to *.

Cors error that i am getting, 错误

Add CORS in node.js express API

In order to add CORS to our API, there are different ways by which you can accomplish this. It could be by manually writing an express middleware and telling your server which requests to allow and from which origin or by using CORS npm library which has done much of the heavy lifting for us.

In this article, we will be using cors npm library which can be easily passed as an express middleware. First of all, install calls on your server-side app by running the command.

npm install cors

Then you can add it as a middleware like this

const express = require("express");
const cors = require("cors");
const app = express();
//use cors as middleware
app.use(cors())

The above code is the default way of adding CORS as an express middleware but what if you want to specify the origin of your client app? Well let's learn different ways to configure CORS in node js app.

Allow requests from all domains.

To allow our node.js server to handle all requests from all domains in our application, we will have to configure cors and pass it an origin key with a wildcard value shown below.

//other imports
app.use(
  cors({
    origin: “*”,
  })
);

The issue with the above configuration is that, you client-side application CAN NOT share cookies nor authentication headers even if the credentials key is passed with a value of true as shown below.

Note: The origin key in cors option CORS take different option types such string, boolean, function or an array.

//other imports
app.use(
  cors({
    origin: “*”,
    credentials: true
  })
)

Another key important thing to note is that, whenever you are not passing withCredentials: true in your client request API, DO NOT pass credentials: true in your cors config server-side most especially if you are using wildcard (*) as the origin of your request header.

Tell CORS to set the origin to the request origin

In order to configure CORS to set the origin to the request origin, simply pass a boolean true value to origin key as shown below;

//other imports
app.use(
  cors({
    origin: true,
    credentials: true
  })
)

Although this will allow your client app to share cookies and auth headers with your server unlike using wildcard but this also is not well secure enough unless it's an open API.

Configure CORS to set the origin to a single domain

In order to configure cors to set the origin to a single domain, simply pass a string true value to origin key as shown below;

//other imports
app.use(
  cors({
    origin: “http://localhost:3000”,
    credentials: true
  })
)

The above configuration will allow your client app to accept requests only from http://localhost:3000 and share cookies and auth headers with your server. This configuration is tightly secure but not robust enough.

Configure CORS to set the origin to multiple whitelisted domains

What if you have microservice applications hosted on different domains or you want different domains to make requests to your API? Well, you can simply configure cors passing by an array of allowed domains to the origin key as shown below;

//other imports
const allowedDomains = [“http://localhost:3000”, “http://localhost:4000”, “http://localhost:6000”]
app.use(
  cors({
    origin: allowedDomains,
    credentials: true
  })
)

The above configuration will allow your client app to accept requests from any of the above domains listed in the array and share cookies and auth headers with your server.

CORS middleware can be passed as a global middleware and on a single route but all the methods shown above are ways to globally configure your CORS within your app. Let's briefly see how we can pass CORS middleware on a single route. Note that, all the ways described above can be used on your routes as well.

const allowedDomains = [“http://localhost:3000”, “http://localhost:4000”, “http://localhost:6000”]
app.get(“/api/posts”, 
  cors({
    origin: allowedDomains,
    credentials: true
  }), 
  (req, res) =>{
    res.send(“everything still works”)
})

NOTE: Whenever you're a making a client-side request with the option of withCredentials: true , ensure your CORS configuration is passed credentials: true as an option as well else cookies won't be shared. Another key important; thing to note is that, whenever you're using wildcard () as the origin, DO NOT use withCredentials: true * on the client and credentials: true on server.

Check your URL

For google cloud functions users

If there is a typo in your URL endpoint such as on functions name, the browser will actually show CORS error.

I had a typo in my URL and wasted a loooot of time searching CORS fixes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM