CORS issue for Ionic + express - angularjs

I have created an application that is accessing/fetching the data from mongo/node+express, which is on different domain(eg domain_name).
The code for the get function is :
var request = $http({
method: 'GET',
url: 'https://domain_name.users.io/categories/list',
withCredentials: true /* to get the Cookie value generated at server-side */
});
At the express side, have added the following code in order to avoid the CORS issue:
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods","GET,PUT,POST,DELETE,OPTIONS");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true");
For the above, i am getting the following error:
XMLHttpRequest cannot load https://domain_name.users.io/data/list. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:8100' is therefore not allowed access.
I have checked the API "https://domain_name.users.io/data/list" and there is no issue with it as i can see the data(when hit on browser).
Could someone please help me for the same

Besides * is too permissive and would defeat use of credentials. So use https://domain_name.users.io/data/list rather than you use *.
You can't do like * because this is a part of security and if you want to allow credentials then your Access-Control-Allow-Origin must not use *.
For more please read here.

Must set the headers:
var request = $http({
method: 'GET',
url: 'https://domain_name.users.io/categories/list',
headers:{'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
withCredentials: true /* to get the Cookie value generated at server-side */
});
==============ON Node Side===============
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization, Access-Control-Allow-Origin, Access-Control-Allow-Headers');
next();
});

Related

Cannot fetch from localhost with Authorization header

I'm having a hard time sending a get request to my expressjs backend with the fetch method.
fetch('http://localhost:9000', { method: 'GET', headers: { Authorization: `Bearer ${accessToken.accessToken}` }}).then(() => {
debugger
}).catch((error) => {
debugger
})
Based on what I could read, this seems correct - The request is however not reaching the API.
I tried constructing the options object like so, without any luck:
const options = {
method: "GET",
headers: headers
};
Without the headers, my request reaches the API. Anyway, the error that I'm getting is this:
error: TypeError: Failed to fetch
If you make that request from an origin other than http://localhost:9000, the Authorization header will cause the browser to make a CORS preflight request OPTIONS http://localhost:9000 before the GET request, and if that fails, the GET request would not be made.
You must ensure that your server handles the preflight, e.g., through the cors middleware.
So I found a solution, basically I added this middleware in my Express application to allow CORS,
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Allow-Methods", "*");
next();
});

No 'Access-Control-Allow-Origin in reactJS

I want to know how set Access-Control-Allow-Origin in axios post method at reactJS or react-native environment?
I use CORS Add-ons and it works but I want to set it in the header too, I try these ways but none of them does not work.
axios.defaults.headers.post['Access-Control-Allow-Origin'] = '*';
and
let axiosConfig = {
headers: {
'method':'POST',
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*',
}
};
You need to enable cross origin request at your server end. A snippet of how you can do it using Express would be as follows
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();
});
This would enable all requests to support CORS. Adapt it as per your requirements.
Check this link for more information if you can not change the server.

How to send both data and header to a server?

I want to send a header to a server using http call POST request.
When I send the header only, everything is ok.
but when I add some data to the call, I get an error:
http://localhost:3000/test_post.
Request header field Content-Type is not
allowed by Access-Control-Allow-Headers in preflight response.
I use node.js as the server side language, this is the code for the CORS settings:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Expose-Headers", "x-auth");
res.header("Access-Control-Allow-Headers", "x-auth");
next();
});
This is the $http call with angular:
$http({
method: 'POST',
data: {name: 'Dani'},
url: 'http://localhost:3000/test_post'
headers: {
'x-auth': 'some token'
}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
console.log('error');
});
I know problem is about the CORS, but I don't know what to modify there,
If I remove res.header("Access-Control-Allow-Headers", "x-auth"); from the CORS I can get the data on the server but not the Header.
How can I get them both?
Hope you can help me with that, Thank you.

Ionic http post to external url

Im trying to send a post to a url with Ionic using angular, but i have the response:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 404.
I know that the external service is working, because i tested it by ajax and everything works perfectly...
Below the code used in AngularJS (Ionic) and Ajax:
Ionic:
var loginServiceUrl = 'http://url.com.br'; //It is not the real one
var loginServiceData = {
email: email#email.com.br
senha: 1234
};
$http.post(loginServiceUrl, loginServiceData).
then(function (res){
console.log(res);
});
Ajax:
$.ajax({
type: "POST",
url : 'http://url.com.br', //It is not the real one
data : {email: 'email#email.com.br', senha: '1234'},
success: function(result) {
$('html').text(JSON.stringify(result));
}
});
Does anyone know why I get the post via ajax on my localhost and not with the ionic, also localhost?
Check this out. It is well explained how to handle issues like yours --> http://blog.ionic.io/handling-cors-issues-in-ionic/
Try to add headers in your POST request.
//example of DataToSend
var DataToSend = {
userID: deviceID,
coordLat : pos.coords.latitude,
coordLon: pos.coords.longitude
};
$http({
method: 'POST',
url: 'http://url.com.br',
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
data: DataToSend
})
CORS has nothing to do with your frontend.
Before sending the POST request, browser send a OPTIONS request to the server to check if call from your domain is allowed or not.
Since, you are getting Status 404, that means your server is not handling the OPTIONS request
1. Allow the OPTIONS request (same as POST)
Now come to second part i.e " Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' "
After allowing the OPTIONS request, now set the response header of OPTIONS request (Browser will check the response of OPTIONS request and then process the POST request only if there is 'Access-Control-Allow-Origin' present in the OPTIONS response.
2. Set the response headers of OPTIONS request
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Allow", "*");
response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent");
Example..
(In Java)
Router:
OPTIONS /*all
controllers.Application.preflight(all)
Controller Function:
public static Result preflight(String all) {
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Allow", "*");
response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent, Auth-Token");
return ok();
}
Hope this will solve your problem.
Cheers

AngularJs $http GET passing custom header returns 404

I've been reading many blogs about it and I could not figure it out how to solve my problem..
I need to pass a token as a custom header to a get $http.. I get an error 404 because the GET request turns into OPTIONS.
The nodejs API Rest is working properly as I test it with the chrome "rest console" app.
Thank you Kasper..
This was my server code before starting this thread..
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", 'X-Requested-With, Content-Type');
res.header('Access-Control-Allow-Methods', 'GET, POST', 'DELETE', 'PUT');
next();
});
With this server code, everytime I send a request (GET) from the client with AngularJS adding a custom header "token"
myapp.factory("Booking", function ($resource) {
return $resource(
serverUrl + "/agp/pricelist",
{}, //default parameters
{
"reviews": {'method': 'GET', 'params': {'reviews_only': "true"}, isArray: true,
headers: {'Content-Type':'application/json', 'token': 'diego' }}
}
);
});
So, when you send a custom header rather than the followings:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type, but only if the value is one of:
application/x-www-form-urlencoded
multipart/form-data
text/plain
the type cors request is not "simple" anymore with a custom header, so when the client makes the request in fact it is making a pre-request with method "OPTIONS" first and then makes the "GET".. in between I was getting 404 error.
I added then to my server:
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", 'X-Requested-With, Content-Type, token');
res.header('Access-Control-Allow-Methods', 'GET, POST', 'DELETE', 'PUT', 'OPTIONS');
res.header('Access-Control-Request-Method', 'GET');
res.header('Access-Control-Request-Headers', 'token');
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
// next();
});
It was supposed to work with the access-control headers I added, but it was still sending back the 404 error.. So the work around was to add
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
Because as I said before, with a custom header the client first ask for permissions with OPTIONS method, and the sends the proper GET or whatever.
I did not find out another solution since this seems to be a work around, but at least I am not stuck anymore.
This is a good and practical link a about CORS
http://www.html5rocks.com/en/tutorials/cors/
Hope this helps someone.
King regards
I'm not too versed with CSRF and the likes, but I do believe this might be the issue I had with contacting my Express server with Angular.
http://mircozeiss.com/using-csrf-with-express-and-angular/
As stated in that article, Angular uses it's own X-XSRF-TOKEN for CSRF protection. Hence, you need to take that into account when setting up your server.
Following along with that guide and Express v3 all my requests going from the client side to the server side, magically started working.
If this is not the case (and I'm way out there), let me know.
What does your full serverside config look like?

Resources