-1

I am setting up a rest api for a personal site. My personal site is built with Vue.js and the api server is built with express. I have tried a couple different CORS configurations on the server but I seem to still get the pre-flight error so I assume I am lacking understanding somewhere.

The original goal was for me to learn about docker by containerizing the api/auth server and hosting it separately from the frontend vue.js app. Is this a part of the problem or bad practice?

Below are the two CORS configs I tried which I found on other posts but have had no success with.

Config #1:

app.use((req, res, next) => {

    res.header("Access-Control-Allow-Origin", "http://0.0.0.0:5000"); // I tried setting a specific IP as well as the * wildcard
    res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
    res.header("Access-Control-Allow-Headers", "Content-type,Accept,X-Custom-Header");

    // I think this if statement should respond the preflight request.
    if (req.method === "OPTIONS") {
        return res.status(200).end();
    }

    return next()

})

Config #2:

const whitelist = [
    'http://0.0.0.0:5000',
];
const corsOptions = {
    origin: function(origin, callback){
        var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
        callback(null, originIsWhitelisted);
    },
    credentials: true
};
app.use(cors(corsOptions));

I am also wondering if it has something to do with how I'm making the request so I've added the method that is being used from the Vue.js app:

attemptLogin: function(event) {
            event.preventDefault()
            axios.post('http://0.0.0.0:5000/auth/login', { 
                username: this.username, 
                password: this.password 
            })
            .then(res => {
                if (res.data.success) {
                    this.updateLoginStatus()
                    this.updateJwt(res.data.token)
                }
            })
            .catch(error => {
                console.log(error)
            });
        }

Other potentially useful information:

I tried running both the frontend and the backend on the same computer with no luck. Now I am running the backend on my laptop and the frontend on my desktop.

Here are the GitHub Repos for both repositories if you need more context:

Frontend: https://github.com/lwerner27/personal-vue

Backend: https://github.com/lwerner27/personal-backend

  • What’s the exact error messages the browser is logging in the devtools console? What’s the HTTP status code of the responses? – sideshowbarker Feb 13 '19 at 16:54
  • Here is a link to a screenshot of the console https://drive.google.com/open?id=1ywS0L0wMSozHO2GoufLvvFmNr2vd-NOf – Luke Werner Feb 13 '19 at 17:04
  • What status code and headers do you get back when you use curl or Postman or something to send an OPTIONS request to `http://10.10.81.100:5000/auth/login`? e.g., using curl, `curl -i -X OPTIONS -H "Origin: http://localhost:8080" http://10.10.81.100:5000/auth/login` – sideshowbarker Feb 13 '19 at 17:08
  • Here is what I got in postman: https://drive.google.com/open?id=1BFUe2tyC2Ub35vZ1nI3p4gfu-fHIRZlp – Luke Werner Feb 13 '19 at 17:21
  • Postman doesn't need to do a pre-flight, so it won't fail. Browsers alone to pre-flight options requests. – Matt Kuhns Feb 13 '19 at 18:03
  • Thank you for your help @sideshowbarker, I got it working by going down to the simplest form of a CORS implementation: app.use(cors()). Which I swear I tried. If you can think of any reason why those other configs wouldn't be sending the Access-Control-Allow-Origin header I'd be interested to hear your thoughts. – Luke Werner Feb 13 '19 at 18:04
  • Your vue site.url is localhost:8080. In config 1 try putting http://localhost:8080 in res.header function – R.Sarkar Feb 14 '19 at 03:56

2 Answers2

0

If you are running from same origin, it shouldn't be a problem. I suspect that you are running Vue app through npm run serve, then pointing it at the back end server, which is running in a different server.

Try creating directory in your backend called public. In Vue, run npm run build and then take the minified files and place them in the public directory.

Then give access to it in node, using express:

app.use(express.static(path.join(__dirname, 'public')));
Matt Kuhns
  • 1,328
  • 1
  • 13
  • 26
  • I understand this method would work. My goal is to have my API on a server that is independent of the vue.js app though. – Luke Werner Feb 13 '19 at 17:07
  • I can't think of a reason to do this. It looks like you are whitelisting your server (port 5000) instead of your localhost:8080. Plus you can't whitelist local host, so you'll need to deploy both of these to a cloud provide OR whitelist your local ip. You are fighting a battle you don't need to fight. – Matt Kuhns Feb 13 '19 at 17:16
  • Here's the reference to inability to whitelist localhost:https://stackoverflow.com/questions/10883211/deadly-cors-when-http-localhost-is-the-origin – Matt Kuhns Feb 13 '19 at 17:17
0

the problem might be that instead of

axios.post('http://0.0.0.0:5000/auth/login', { 
                username: this.username, 
                password: this.password 
            })

try using http://0.0.0.0:5000/auth/login/ I used to have preflight error also on mozilla and other browsers if it's not slashed at the end. May i know what's the exact CORS error you are having?

Badabomb
  • 11
  • 1