I try to build a platform, which consists of 2 separated parts, the backend and the frontend. The backend is powered by Express.js and Passport.js. It's available via localhost:3000. The frontend uses Googles polymer-1.0 and is running on localhost:8001.
I want to do all API stuff on my backend. The Ui calls and get data from the backend.
When try to do an iron-ajax request for authorization to my backend route, I'm getting a CORS error:
XMLHttpRequest cannot load http://localhost:3000/auth/facebook. The request was redirected to 'https://www.facebook.com/v2.2/dialog/oauth?response_type=code&redirect_uri=…%3A3000%2Fauth%2Ffacebook%2Fcallback&scope=email&client_id=0815', which is disallowed for cross-origin requests that require preflight.
UI snippet:
iron-ajax id="login" url="" method="GET" headers='{"X-Requested-With": "XMLHttpRequest"}' handle-as="json" on-response="hresponse" debounce-duration="300"> /iron-ajax> _handleTap: function () { var url = 'http://localhost:3000/auth/' + this.service; this.$.login.url = url; this.$.login.generateRequest(); },
Backend snippet:
app.get('/auth/facebook', passport.authenticate('facebook', { scope: 'email' })); app.get('/auth/facebook/callback', passport.authenticate('facebook'), function(req, res) { res.status(200).json({ success: true, message: 'Enjoy!', redirect: '/route/to/nowhere', }).end(); });
As you can see, I'm just using the simple Facebook auth snippet from passport.js documenation .
There were 2 request proceeded: PREFLIGHT:
RESPONSE HTTP/1.1 200 OK X-Powered-By: Express Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept Allow: GET,HEAD Content-Type: text/html; charset=utf-8 Content-Length: 8 ETag: W/"8-8ww6QOmj5lyGjHVKXelZGQ" Date: Tue, 26 Jan 2016 12:59:20 GMT Connection: keep-alive REQUEST OPTIONS /auth/facebook HTTP/1.1 Host: localhost:3000 Connection: keep-alive Access-Control-Request-Method: GET Origin: http://localhost:8001 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36 Access-Control-Request-Headers: accept, x-requested-with Accept: */* DNT: 1 Referer: http://localhost:8001/ Accept-Encoding: gzip, deflate, sdch Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
GET:
RESPONSE HTTP/1.1 302 Found X-Powered-By: Express Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept Location: https://www.facebook.com/v2.2/dialog/oauth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Ffacebook%2Fcallback&scope=email&client_id=0815 Content-Length: 0 Date: Tue, 26 Jan 2016 12:59:20 GMT Connection: keep-alive REQUEST GET /auth/facebook HTTP/1.1 Host: localhost:3000 Connection: keep-alive accept: application/json Origin: http://localhost:8001 x-requested-with: XMLHttpRequest User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36 DNT: 1 Referer: http://localhost:8001/ Accept-Encoding: gzip, deflate, sdch Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
My node.js server also accepts CORS requests
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
When using localhost:3000/auth/facebook as a link, I get my json response from the backend and on port 3000, but that is not what I want.
Is there a possibility to handle such API requests via an own API interface, like mine? Currently I see here a big show stopper.
Thanks & BR; andre
I think the issue has to do with redirection and CORS. Redirections with the status codes of 301, 302, 303, 307, or 308, will get you an error. This is being changed, but for now you need a workaround such as sending back the redirect URL in the response header or body, without using a redirect.
This is well explained in this reply
The only way for a user to authenticate with Facebook is if you actually send the user to Facebook. Doing an XMLHttpRequest won't work because there is no way for the user to login to their Facebook account, approve your application, etc. You must actually redirect the user's browser.
Change your _handleTap
function to this:
_handleTap: function () {
var url = 'http://localhost:3000/auth/' + this.service;
window.location = url
}
You need to add this middleware to all your request this way
app.all('/*', function(req, res, next) { res.header('Access-Control-Allow-Origin', req.headers.origin || '*'); res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS'); res.header('Access-Control-Allow-Headers', 'content-Type,x-requested-with'); next(); });
like explained here How to allow CORS in Express/Node.js?
This error basically means, the server is not accepting Cross Origin Requests (Requests from other domains). In express.js you can use a middleware to enable your server to do this.
var cors = require('cors');
app.use(cors());
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.