It's been two days and a million tries to enable CORS when trying to authenticate a user with Facebook using Passport in NodeJS/Express.
The error I get on Chrome is this:
XMLHttpRequest cannot load https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http%…%3A8080%2Fauth%2Ffacebook%2Fcallback&scope=email&client_id=598171076960591. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
The routes I use are as simple as that:
// ===================================== // FACEBOOK ROUTES ===================== // ===================================== // route for facebook authentication and login app.get('/auth/facebook', passport.authenticate('facebook', { scope : 'email' })); // handle the callback after facebook has authenticated the user app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect : '/home', failureRedirect : '/login' }));
This is how the route is called on my angularJS file (I've also tried setting withCredentials : true):
$http.get('/auth/facebook') .success(function(response) { }).error(function(response){ });
I've tried a dozen solutions that I found here on StackOverflow and other forums.
I tried adding this on the before my routes on the routes.js files:
app.all('*', function(req, res, next) { res.header('Access-Control-Allow-Origin', '*'); res.header("Access-Control-Allow-Headers", "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name"); res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS'); res.header('Access-Control-Allow-Credentials', true); if ('OPTIONS' == req.method) { res.send(200); } else { next(); } });
I tried adding this on server.js file (note that I changed header to setHeader but I've tried both):
app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type,X-Requested-With'); res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS'); res.setHeader('Access-Control-Allow-Credentials', true); if ('OPTIONS' == req.method) { res.send(200); } else { next(); } }); require('./app/routes.js')(app, passport);
I tried adding this on my app.js file (angularJS configurations):
$httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; $httpProvider.defaults.withCredentials = true;
Anyway, I don't know what else to do. Everything I found online didn't work. Is there a chance it has something to do with me using AngularJS Routing? I don't see any reason why this would matter, but I kinda ran out of guesses.
My situation is very similar to this one: Angular/Node/Express/Passport - Issues when connecting to facebook(CORS)
Thanks in advance!
Note: Even if your backend server is running on a localhost with a different port it is treated as a different domain. So CORS issues may occur while developing an angular application. How to fix CORS issues?
To add authentication to the Angular dashboard app, you need to add routes to the Angular application. From the project directory, execute the following command: It should create the routing module. Open app-module.routing.ts and replace it with the following code:
We can fix cross issues in two way: One way to fix it is by enabling proper CORS headers request on the server-side. Another way is to configure Angular CLI proxy.
One way to fix it is by enabling proper CORS headers request on the server-side. Another way is to configure Angular CLI proxy. Note: The correct approach or solution is to configure the backend server, but that may not always be feasible.
I was having this issue and almost reached the point where I was convinced I could find no solution, but looking at a simple tutorial again (http://mherman.org/blog/2013/11/10/social-authentication-with-passport-dot-js/) solved it for me. I was trying to make an API call from Angular to Node.js, which is going to always bring you those XMLHttpRequest errors despite what you configure on the server, CORS or not! CORS is not the fixture - if you opened your Chrome network console, you'll find that your request to Google or Facebook or whatever 3rd party site is out of your control to change - it was triggered from a 302 redirect that was sent back to your frontend, something that Angular.js or any other framework has no power to control, thus you can't really add "Access Control Allow Origin" to that request anyway.
The solution is simply to make the button or text that says "Sign In with _____" a LINK. A literal <a href="/auth/facebook"></a>
link. That's it.
Of course, I also met with a lot of other stumbling blocks and gotchas in the process. I tried to not use the default middleware for passport.authenticate('facebook'), but tried to wrap it in a function(req, res, next){ ... }
, thinking that would do something, but it doesn't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With