Reputation: 21
While using an Express/NodeJS backend - I have a REST GETTER that is used to authenticate using strava (passport-strava)
When I invoke the API URL directly(http://localhost:3000/api/auth/strava) - the connection is successful and I'm able to retrieve the profile information. However, when this is invoked through a browser widget, i.e. onClick of a HTML button and routed through to the backend - I'm thrown an error
XMLHttpRequest cannot load https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
I do understand that this is related to CORS and that the header "Access-Control-Allow-Origin" must be included however, there is no respite on adding this into the header with the appropriate value.
I tried to intercept the calls using chrome://net-internals to check if Access-Control-Allow-Origin is being stripped out and noticed the variations in calls -
When called directly via the API - the calls are as follows
1097271 URL_REQUEST http://localhost:3000/api/auth/strava
1097273 DISK_CACHE_ENTRY http://localhost:3000/api/auth/strava
1097275 HTTP_STREAM_JOB https://www.strava.com/
1097276 CONNECT_JOB ssl/www.strava.com:443
1097277 CONNECT_JOB ssl/www.strava.com:443
1097278 SOCKET ssl/www.strava.com:443
1097279 CONNECT_JOB ssl/www.strava.com:443
1097280 CONNECT_JOB ssl/www.strava.com:443
1097281 SOCKET ssl/www.strava.com:443
1097282 DISK_CACHE_ENTRY https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097283 HTTP_STREAM_JOB https://www.strava.com/
1097285 URL_REQUEST http://localhost:3000/api/auth/strava
1097288 DISK_CACHE_ENTRY http://localhost:3000/api/auth/strava
1097290 HTTP_STREAM_JOB https://www.strava.com/
1097291 DISK_CACHE_ENTRY https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097292 HTTP_STREAM_JOB https://www.strava.com/
1097293 DISK_CACHE_ENTRY http://localhost:3000/api/auth/strava/callback?state=&code=7b5722c72f079ee2ac5dfeb7d5140cdc6375f5cc
However, when routed via the widget the calls are as follows
1097337 URL_REQUEST http://localhost:3000/api/auth/strava
1097339 DISK_CACHE_ENTRY http://localhost:3000/api/auth/strava
1097344 URL_REQUEST https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097346 DISK_CACHE_ENTRY https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097347 HTTP_STREAM_JOB https://www.strava.com/
1097348 CONNECT_JOB pm/ssl/www.strava.com:443
1097349 CONNECT_JOB pm/ssl/www.strava.com:443
1097350 HOST_RESOLVER_IMPL_JOB www.strava.com
1097352 SOCKET pm/ssl/www.strava.com:443
1097353 CONNECT_JOB pm/ssl/www.strava.com:443
1097354 SOCKET pm/ssl/www.strava.com:443
The difference that I seemed to pull out is the additional call
1097344 URL_REQUEST https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
which isn't made in the previous scenario.
These observations are made not only for the passport-strava package but the passport-facebook package as well. Therefore, I think there is something gravely incorrect that I'm doing to get into this state.
Any assistance is well appreciated.
Upvotes: 0
Views: 450
Reputation: 19248
Since you already know about CORS then I go into any details.
Basically your issue is with your REST server
, it needs to set the response packet's header with the appropriate content so that the browser doesn't complain. Unfortunately this is a security feature.
So in your server code, you need to define a function that would do the above and set it as 1 of the middleware layer that express will have to parse when a HTTP comes through.
Example:
var express = require('express');
var app = express();
var httpAccessControlPolicy = function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key,Authorization');
res.setHeader('Access-Control-Allow-Credentials', false);
next();
};
app.use(httpAccessControlPolicy);
Yes. As pointed out by 1 of the commenter the npm module cors
can also do the job.
CORS: https://www.npmjs.com/package/cors
If you are intending to use it then you might be looking at this example usage:
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
app.get('/products/:id', function(req, res, next){
res.json({msg: 'This is CORS-enabled for all origins!'});
});
app.listen(80, function(){
console.log('CORS-enabled web server listening on port 80');
});
Upvotes: 1