No 'Access-Control-Allow-Origin' is presen

2019-04-11 14:28发布

问题:

I have a site that is using Passport Steam Strategy. My server (Node with Express) is currently running on localhost:3000 while my front end is running on localhost:8080. I keep running into a cross-origin issue, only when attempting to authorize through Steam. My requests are made through Axios and I am using CORS. I've spent hours Googling and trying various things but I can't seem to get it to work.

This is the error that I get:

XMLHttpRequest cannot load https://steamcommunity.com/openid/login?openid.mode=checkid_setup&openid.ns…3000%2Fsteam%2Fauth%2Freturn&openid.realm=http%3A%2F%2Flocalhost%3A3000%2F. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

Here is where the route is called from the front end:

    linkSteam(){
        api('http://localhost:3000/steam/auth')
            .then(res => {
                console.log(res);
                state.user = res.data.user;
            })
    }

And here is my axios configuration on the front end.

let api = axios.create({
  baseURL: 'http://localhost:3000/api/',
  timeout: 3000,
  withCredentials: true
})

My CORS is set up as follows

var whitelist = ['http://localhost:8080', 'https://steamcommunity.com', 'http://localhost:3000', 'null'];
// I added null here as someone said that it worked as their origin displayed null like mine does
var corsOptions = {
  origin: function (origin, callback) {
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
    callback(null, originIsWhitelisted);
  },
  credentials: true
};

I then import my CORS into my main file and use it as follows

app.use(cors(corsOptions))
app.use('*', cors(corsOptions))

I kept seeing that you can set your Access-Control-Allow-Credentials, etc and did so

app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-Credentials', true);
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080');
  res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
  if ('OPTIONS' == req.method) {
     res.send(200);
   } else {
     next();
   }
});

This didn't help. I've tried breaking down my original function where /steam/auth is called and running a console.log(req.headers.origin) and spits back my correct URL, but then the error still reports that the Origin is null. If I set my Access-Control-Allow-Origin' to '*', I get a slightly different error that I must provide credentials, and that the Origin 'localhost:8080' is therefore not allowed.

Here's my /steam/auth route.

router.get('/steam/auth',
  passport.authenticate('steam', {
    failureRedirect: '/'
  }),
  function (req, res) {
    res.redirect('/');
  });

And this does work if I click on the URL that cannot be loaded and then login to Steam. It will then redirect me back to my site with my Steam profile information intact. The error is on attempting to get the initial redirect back to Steam in order to login. I have also tried doing this in a res.redirect to their direct URL and I get the same error.

Thanks in advance for any help! And let me know if I'm missing vital information. I've tried to include everything, but I wouldn't be surprise if I missed something.

回答1:

If the error message in the question is the actual message the browser is reporting, it’s because your client-side code is trying to send a request to https://steamcommunity.com/openid/login.

So given that, no matter what config changes you make to your Node server on localhost:3000, that’s not going to change anything. Instead it seems like you you need to figure out where your client-side code is sending a request to https://steamcommunity.com/openid/login and why.

And the reason the request to https://steamcommunity.com/openid/login fails is that server doesn’t include the Access-Control-Allow-Origin response header in its response.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS has more details.

So because you can’t change the server’s behaviour, your browser will continue so block your code from getting at the response as long as it lacks the Access-Control-Allow-Origin header.

I don’t know how authorization is handled by Steam but maybe you instead need to either make the authorization request to Steam through your existing Node backend somehow, or else set up your own CORS proxy using, e.g., https://github.com/Rob--W/cors-anywhere/, and proxy your client-side authorization request to Steam through it.