4

I am trying to set CORS for my Express.js backend. Since I have a local and a remote version of the front end I want to allow a couple of URLS access to the backend. I have tried to use "*" and var cors = require('cors') app.use(cors()) but I get

Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.

I have tried using the dynamic settings for cors(), but there were no examples how to use it with Express's routes. I am now trying to create my own white list check with the code below but now I am getting

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access. The response had HTTP status code 500.

What am I doing wrong?

UPDATE: It looks like the if statement is blocking the headers from being added so I tried to remove it to see what is happening with res.header('Access-Control-Allow-Origin', req.get("origin")); It is now giving me

Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials.

var whiteList = {
    "http://localhost:5000": true,
    "https://example-url.herokuapp.com": true
};
var allowCrossDomain = function(req, res, next) {    
        if(whiteList[req.get('Origin')]){            
            res.header('Access-Control-Allow-Credentials', true);
            res.header('Access-Control-Allow-Origin', req.get('Origin'));
            res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
            res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, Origin, Accept');        
            next();
        } 
};
app.use(allowCrossDomain);
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
EasilyBaffled
  • 3,822
  • 10
  • 50
  • 87
  • _“The response had HTTP status code 500”_ – well that sounds like your headers where not send at all, because you managed to create an error in your code. – CBroe Mar 22 '15 at 15:49
  • Which Browsers are you seeing this error? Try more than one. – talves Mar 22 '15 at 15:52
  • @talves Safari has the same result. – EasilyBaffled Mar 22 '15 at 16:14
  • #CBroe I have a feeling that is related to 'if(allowedURLS.indexOf(req.get("origin")) > -1) {' more specifically 'req.get("origin")' I'm just not sure why. – EasilyBaffled Mar 22 '15 at 16:15
  • Is the [`app.use(allowCrossDomain)` above all other](http://stackoverflow.com/questions/11001817/allow-cors-rest-request-to-a-express-node-js-application-on-heroku?answertab=votes#tab-top) `app.use`? – talves Mar 22 '15 at 16:26
  • @talves I had seen that one, and yes I made sure its at the top. – EasilyBaffled Mar 22 '15 at 22:37
  • @EasilyBaffled, I don't see where you're using `whitelist`, or where you're setting `àllowedURLS`. – Maria Ines Parnisari Mar 22 '15 at 23:03
  • @l19 the whitelist is the first line in my code example. It is an array of two urls. The allowedURLS, if I understand your meaning, is set in Access-Control-Allow-Origin on line 4, the first statement inside the if block. – EasilyBaffled Mar 22 '15 at 23:15
  • Shouldn't the 3rd line be `if(whitelist.indexOf(...)`? – Maria Ines Parnisari Mar 22 '15 at 23:27
  • @EasilyBaffled, are you sure you're setting the `Origin` header in the request? Have you tried with `if (whiteList[req.headers.host]) {`? – Maria Ines Parnisari Mar 23 '15 at 00:22
  • I'm not sure I am setting it properly, I think that's the problem. req.header.host returns the url of the backend, not what I need. – EasilyBaffled Mar 23 '15 at 01:05

1 Answers1

2

This ultimately came down to a spelling/understanding error. I was trying to get the request origin by using req.headers.Origin. Turns out there is no 'Origin' in headers, I had to use req.headers.origin instead. The code bellow will work, and let you use multiple urls for CORS, it does not yet easily handle something like http://localhost:5000/route or a situation where the provided origin isn't in the list.

var whiteList = {
    "http://localhost:5000": true,
    "https://example-url.herokuapp.com": true
};
var allowCrossDomain = function(req, res, next) {    
        if(whiteList[req.headers.origin]){            
            res.header('Access-Control-Allow-Credentials', true);
            res.header('Access-Control-Allow-Origin', req.headers.origin);
            res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
            res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, Origin, Accept');        
            next();
        } 
};
app.use(allowCrossDomain);
EasilyBaffled
  • 3,822
  • 10
  • 50
  • 87