Angularjs Access-Control-Allow-Origin - angularjs

I have Angularjs app connects to a server using API, and i'm using token authentication, when i use Postman to get the token, it works perfect, but when i'm use Angulajs with the same header and parameters i got error:400.
When i checked both requests using Fiddler, i found that the request from Angularjs is missing Access-Control-Allow-Origin: * header.
How to fix this?
Here is the service used to get the token:
AuthenticationApi.Login = function (loginData) {
//POST's Object
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
var deferred = $q.defer();
//the data will be sent the data as string not JSON object.
$http.post('http://localhost:53194/Token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
.then(function (response) {
console.log(response);
localStorageService.set('authorizationData',
{
token: response.access_token,
userName: loginData.userName
});
Authentication.isAuth = true;
Authentication.userName = loginData.userName;
console.log(Authentication);
deferred.resolve(response);
},
function (err, status) {
logout();
deferred.reject(err);
});
return deferred.promise;
};
for the API server, i'v done CORS:
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}

i found the problem and i fixed it.
in the API server, i have this code:
var cors = new EnableCorsAttribute("*", "*", "*");
cors.PreflightMaxAge = 60;
config.EnableCors(cors);
The problem is in the PreflightMaxAge, i just commented it...It worked!!!
if the problem not solved, try to use IE or FireFox, don't use Chrome because it is not CORS enabled

Related

CORS error while sending request from Browser to play server even after sending CORS header

I have a REST API developed using Play Framework/Java and front end developed in Angular JS.
I am trying to call a POST method fron the Angular Client to the server using the following code:
$scope.login = function () {
console.log('login called');
var loginURL = 'http://localhost:9000/login';
var loginInfo = {
'email': $scope.email,
'password': $scope.password
};
$http({
url: loginURL,
method: 'POST',
data: loginInfo,
headers: { 'Content-Type': 'application/json' }
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.greeting = response.status;
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
This is the code at my server:
public Result doLogin() {
ObjectNode result = Json.newObject();
result.put("status", "success");
return ok(result).withHeader("Access-Control-Allow-Origin", "*");
}
And this is the application conf file:
#allow all hosts.
play.filter.hosts {
allowed = ["."]
}
#allow CORS requests.
play.filters.cors {
allowedOrigins = ["*"]
}
Yet even after enabling CORS, I am getting error in console in both Firefox and Google Chrome:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:9000/login. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
ERROR: {"data":null,"status":-1,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"http://localhost:9000/login","data":{"email":"xxx","password":"xxx"},"headers":{"Content-Type":"application/json","Accept":"application/json, text/plain, /"}},"statusText":""}
I do know that the server is sending the correct response and the correct header because when I do the POST from Postman, I can see the response and also the headers containing {"Access-Control-Allow-Origin", "*"} in Postman.
So then, what could be the problem? Is there something I am missing from the Client side?
The difference between POSTMAN request and browser request is browser sends an OPTIONS request before the actual POST / GET request.
To be able to accept OPTION request with your play framework allowedHttpMethods = ["GET", "POST" ,"OPTIONS"]
for follow this link
Play Framework 2.3 - CORS Headers
This causes a problem accessing CORS request from a framework (like angularjs). It becomes difficult or the framework to find what was the options request for and take action properly.
For fixing your problem you will need to analyze how the options request going and how it's being interpreted and how to overcome. But in general, I suggest using "fetch" built-in request for this, which supports the promises so can be chained easily with angularjs code
so your code will look something like this
$scope.login = function () {
console.log('login called');
var loginURL = 'http://localhost:9000/login';
var loginInfo = {
'email': $scope.email,
'password': $scope.password
};
fetch(loginURL, {
method: 'post',
headers: {
"Content-type": "application/json"
},
body: loginInfo
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.greeting = response.status;
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}

req.body is null in expressjs server when sending post request from ionic app

I am developing an ionic app when I am sending a post request using angularjs $http.post to my express js server, I cannot see the data in the req.body.
I am running my server on localhost:3000
Code in my server for CORS
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type");
res.header("Access-Control-Allow-Methods", "GET,PUT,DELETE,POST");
next();
});
My angular Js post request
$http.post('http://localhost:3000/signup',{"username":"x","password":"y"}).success(function(res){
console.log(res);
if(res.msg=="success")
{
//do something
}
}
I am able to see data in req.body as "key" like:
{'{"username":"x","password":"y"}':''}
When I am setting the header from ionic app as:
$http.defaults.headers.post["Content-Type"] = 'application/x-www-form- urlencoded; charset=UTF-8';
Please let me know how to debug this
You are getting the entire data as key in req.body. This is because the angular request that you are making is wrong. Here is the part of code that should work
$http({
url: 'http://localhost:3000/signup',
method: "POST",
data: { username : "a" , password : "b" }
})
.then(function(response) {
// success
},
function(response) { // optional
// failed
});
Well I figured that out
I have used this stackoverflow link Ionic framework http post request to parse my data before its send to my server
$http.defaults.headers.post["Content-Type"] = 'application/x-www-form-urlencoded; charset=UTF-8';
Object.toparams = function ObjecttoParams(obj)
{
var p = [];
for (var key in obj)
{
p.push(key + '=' + encodeURIComponent(obj[key]));
}
return p.join('&');
};
$http({
url: 'http://localhost:3000/signup',
method: "POST",
data: Object.toparams(u)
})
.then(function(response) {
console.log(response);
},
function(response) { // optional
// failed
});

Auth0 NodeJS Authentification Refused using npm request

I'm facing a problem, I tried to connect to Auth0 API to enable a strong identification on my WebApp.
For context :
Front-End : I'm using an angularJS front, and there I implemented the Lock Library to manage the Auth0 popup by following this webapp-specific tutorial.
Back-End : NodeJS & Express server, in order to verify the user's authentification, I use the npm lib "request" to call the Auth0 API.
If i understand well, a click on the auth0 widget sends a request to the specified endpoint URL, and it's received by the back-end:
app.get('/auth0CallbackURL', function (req, res) {
console.log(req.query.code);
var auth0code = req.query.code;
var client_secret = PROCESS.ENV.SERCRETID;
var domain = PROCESS.ENV.DOMAIN;
var client_id = PROCESS.ENV.CLIENTID;
var redirectUrl = PROCESS.ENV.REDIRECTURL;
var request = require('request'); // request-promise
var requestParams = {
url: 'https://mycompanydomain.auth0.com/oauth/token?client_id='+client_id+'&redirect_uri='+redirectUrl+'&client_secret='+client_secret+'&code='+auth0code+'&grant_type=authorization_code',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
And then I call request() to get back the access_token and verify the authentification.
request(requestParams, function(err, data) {
if (err) {
console.log('Err:', err);
} else {
console.log('response body: ', data.body)
}
But the only result I get is :
{
"error": "access_denied"
"error_description": "Unauthorized"
}
At the begining i thougt it was my Auth0 configuration that's didn't allow my authentification, but it seems that there are OK.
Thanks in advance for your replies.
As per the page you linked, you need to pass the following information:
client_id=YOUR_CLIENT_ID
&redirect_uri=https://YOUR_APP/callback
&client_secret=YOUR_CLIENT_SECRET
&code=AUTHORIZATION_CODE
&grant_type=authorization_code
in the request body and with a content type of application/x-www-form-urlencoded.
You're setting the content type correctly, but then are passing the data in the URL query component and instead you need to pass it the POST request body.
Using request package you should do the following:
var requestParams = {
url: 'https://mycompanydomain.auth0.com/oauth/token',
method: 'POST',
body: 'client_id=' + client_id +
'&redirect_uri=' + redirectUrl +
'&client_secret=' + client_secret +
'&code=' + auth0code +
'&grant_type=authorization_code',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}

Drupal REST return 301 after logging in from ionic application

I have web application based on drupal 7, and I want to create ionic app connected with that web app using REST.
Login action work good, but after login I always get status 301 Moved Permamently, no matter what I call from REST.
But when I do the same using ARC or POSTMASTER all works good. I can call login successfully, get token successfully, and logout without any problem.
I guess the reason is not set header properly. When I use ARC or POSTMASTER my request contains Cookie with session_name and sessid received from drupal during login.
Also I cant set X-CSRF-Token in header.
But when I attempt to set it on angular nothing changes on request [headers are not set].
My login controller on ionic(angular):
var login = function(name, pw) {
return $q(function(resolve, reject) {
var data = "username="+name+"&password="+pw;
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
}
$http.post('http://example.com/user/login.json', data, config)
.then(
function(response){
// success callback
storeUserCredentials(name + '.' + response.data.token, response.data.session_name, response.data.sessid);
storeUserRole(response.data.user.roles);
resolve('Login success.');
},
function(response){
// failure callback
//console.log('error '+response);
reject('Login Failed.');
}
);
});
};
My logout controller on ionic(angular):
var logout = function() {
var data = "username="+name+"&password="+pw;
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'X-CSRF-Token': token,
'Cookie':session_name + '=' + sessid
}
}
$http.post('http://example.com/user/logout.json', data, config)
.then(
function(response){
// success callback
destroyUserCredentials();
},
function(response){
// failure callback
destroyUserCredentials();
}
);
};
This technique works for me
I store the 'minimal' config object as a starting point. This object is created using the response from /services/session/token as the data in the following:
localStorageService.set('HTTP_CONFIG', {
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'X-CSRF-Token': data
}
});
Contrary to many examples online, I find it unnecessary to set the cookies manually. In fact, attempting to set cookies often results in errors. In this example I'll use local storage to produce copies of the http config.
Next, I ascertain if I'm logged in or not.
var tokenConfig = localStorageService.get('HTTP_CONFIG');
tokenConfig.url = APP_CONFIG.REST_API + '/system/connect.json';
tokenConfig.method = 'POST';
tokenConfig.data = {};
$http(tokenConfig) ...
I simply carry forward in this manner, for instance:
var loginConfig = localStorageService.get('HTTP_CONFIG');
loginConfig.method = 'POST';
loginConfig.url = APP_CONFIG.REST_API + '/user/login';
loginConfig.data = { username: username, password: password };
$http(loginConfig) ...
I simply carry forward using the same 'minimal' http config object, adding properties as required. This has worked perfectly for me.

parse.com POST call from angularjs CORS error

I am using parse.com cloud code and has a function inside, which is called using a https post call from my angularjs.
When I test the same function from POSTMAN REST client it works.
But from my domain it gives a CORS error
XMLHttpRequest cannot load
https://api.parse.com/1/functions/sendemail. Response to preflight
request doesn't pass access control check: A wildcard '*' cannot be
used in the 'Access-Control-Allow-Origin' header when the credentials
flag is true. Origin 'http://www.crickify.com' is therefore not
allowed access.
Cloud Code:
Parse.Cloud.define("sendemail", function(request, response) {
//response.success("Hello world!");
var mailgun = require('mailgun');
console.log("from parselog",request.params);
response.set("Access-Control-Allow-Origin", "http://www.crickify.com");
response.set("Access-Control-Allow-Headers", "X-Requested-With");
response.set('Access-Control-Allow-Headers', 'Content-Type');
mailgun.initialize('XXX', 'XXX');
mailgun.sendEmail({
to: "bala#mindlens.com.sg",
from: "Mailgun#CloudCode.com",
subject: "Hello from Cloud Code!",
text: "Using Parse and Mailgun is great!"
}, {
success: function(httpResponse) {
console.log(httpResponse);
response.success("Email sent!");
},
error: function(httpResponse) {
console.error(httpResponse);
response.error(httpResponse);
}
});
});
Angular Code:
$scope.sendemail = function(passedEmail) {
// body...
var email = passedEmail;
var message = {mail:email};
$http({
method: 'POST',
url: 'https://[app key]:jskey]#api.parse.com/1/functions/sendemail',
data: message
})
.success(function(data) {
console.log("Success" + data);
})
.error(function(error) {
console.log("Success" + data);
});
}

Resources