Broadcast headers to all resources after calling another one resource - angularjs

I built a rest api, now it's time to handle data with angular. To do that, I built a service to make a connection to my resources.
So I've :
angular.module("myServiceRest", ['ngResource'])
.factory("myService", function ($rootScope, $resource) {
var apiData = $resource(
"/api", {},
{
"getContains": {method: 'GET', isArray: false, url: "/api/users/:userid/:yearid/:groupeid/:levelid", headers: $rootScope.headers},
"getContain": {method: 'GET', isArray: false, url: "/api/Contains/:containid", headers: $rootScope.headers},
"postAuthTokens": {method: 'POST', url: "/api/auth-tokens"}
});
return {
getGroupesContenus: function (user_id, year_id, groupe_id, level_id) {
return apiData.getContains({userid: user_id, yearid: year_id, groupeid: groupe_id, levelid: level_id});
},
getContain: function (contain_id) {
return apiData.getContain({containid: contain_id});
},
postAuthTokens: function(userData) {
apiData.postAuthTokens(userData, function (data) {
console.log("success !");
$rootScope.headers = {
"Content-Type": "application/json",
"Authorization": "Basic ZWRnYXJrYW1kZW06TkVXVE9O",
"Accept": "application/json",
"X-Auth-Token": data.value
};
}, function (error) {
console.log(error.data);
})
}
}
});
Here I have 3 resources :
getContains: /api/users/:userid/:yearid/:groupeid/:levelid
getContain: /api/Contains/:containid
postAuthTokens: /api/auth-tokens
To get access to getContains and getContain (after logged in), the user need to set a token (X-Auth-Token) retrieved through postAuthTokens.
Basically, when the user log in, he calls the POST resource postAuthTokens, and retrieve his token (stored in a database) through data.value, and have to set that token in X-Auth-Token in order to continue.
For that, I created a $rootScope, and immediately when the user get log in, I set :
$rootScope.headers = {
"Content-Type": "application/json",
"Authorization": "Basic ZWRnYXJrYW1kZW06TkVXVE9O",
"Accept": "application/json",
"X-Auth-Token": data.value //Set the user token
};
But it doesn't work at all. It's like $rootScope.headers got reinitialize after calling post Auth Tokens, because, when the user log in I got this error in my Chrome console afterward:
angular.js:14328 Possibly unhandled rejection: {"data":{"error":{"code":500,"message":"Internal Server Error","exception":[{"message":"X-Auth-Token header is required","class":"Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException","trace":...
My $rootScope.headers wasn't set at all.
So how can I broadcast my $rootScope.headers to all resource headers after calling postAuthTokens ?

Instead of adding the headers to the root scope, add them to the $http service:
$http.defaults.headers.common['X-Auth-Token'] = data.value
They should then be added to all subsequent HTTP requests automatically

Related

CORS post call not working in Angularjs

I am trying to implement cross-origin post call from angularjs application, then I get the following error.
Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
But, when I make a Ajax call it works properly.
How HTTP post call work in angularjs?
Ajax call
$.ajax({
type: 'POST',
url: getAccessTokenUrl,
data: JSON.stringify(clintdata),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(resultData) {
console.log(resultData);
},
error: function (request, status, error) {
console.log(status);
}
});
Angularjs HTTP call
$http({
method: 'POST',
url: getAccessTokenUrl,
data: clientdata,
headers: {
'Authorization': undefined,
'Auth-Token': undefined
}
}).then(function(res){
console.log(res);
}, function(err){
console.log(err);
});
I have some default setting. Authorization is for others REST
$http.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8;' ;
$http.defaults.headers.common['Auth-Token'] = 'X-Requested-With';
$http.defaults.headers.common['Authorization'] = $('#Authorization').val();
Access-Control-* headers are response headers. They come from the server in response to a request. You do not apply them to your request headers.
If your jQuery request works correctly without adding any additional headers, then your AngularJS request should work the same.
The equivalent jQuery request in AngularJS (including removing the Authorization and Auth-Token headers you've set via defaults) is
$http.post(getAccessTokenUrl, clientdata, {
headers: {
Authorization: undefined,
'Auth-Token': undefined
}
}).then(response => {
console.log(response.data)
})
or the long version
$http({
method: 'POST',
url: getAccessTokenUrl,
data: clientdata,
headers: {
Authorization: undefined,
'Auth-Token': undefined
}
}).then(...)
AngularJS by default...
POSTS requests as application/json content-type
Serializes the data property to JSON
Expects a JSON response
Resolves the $http promise with a response object with the response body parsed as JSON into the data property
Remove the following setting
$http.defaults.headers.common['Auth-Token'] = 'X-Requested-With';
$http.defaults.headers.common['Authorization'] = $('#Authorization').val();
Add Authorization header dynamically from Interceptor
request: function(config) {
if (angular.isUndefined(config.skipInterceptor) || !config.skipInterceptor) {
// add Authorization token
}
return config;
}
Http call like this
$http.post('your url', {
skipInterceptor: true
})

restdb.io wont let me access with GET verb although I got CORS enabled

I have CORS enabled in restdb.io. I have set up so all origins are allowed to make GET requests. I have generated a Api key .This is the error message and api call. The wierd thing is that if I click the request in the network tab in chrome dev mode I can see it got 200 ok from the server. Am I missing something?
No 'Access-Control-Allow-Origin' header is present on the requested resource.
I am using Angular JS.
function getImages() {
var def = $q.defer();
$http({
async: true,
crossDomain: true,
url: getImagesURL,
method: "GET",
headers: {
"content-type": "application/json",
"x-apikey": APIKEY,
"cache-control": "no-cache"
}
}).then(function successCallback(response) {
def.resolve(response.data);
}, function errorCallback(response) {
console.log("Error " + response.data)
});
return def.promise;
}
Solved it. I was using the wrong api key.

How to handle CORS requests in AngularJS

I'm facing problem with CORS requests in AngularJS while calling web services but the same service able to call by using jQuery.
Note: From server side we are receiving header "Access-Control-Allow-Origin:*" and these services are running fine in jQuery application.
Here I'm posting my AngularJS code as well as jQuery code.
AngularJS:
$http({
method: 'POST',
url: $rootScope.host + "UserLogin",
//headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: {
"uname": $scope.uname,
"password": $scope.password
},
}).then(function (success) {
$scope.loginDetails = success;
console.log($scope.loginDetails);
}),function (error){
console.log(error);
});
If I pass the header like headers: { 'Content-Type': 'application/x-www-form-urlencoded' } able to ping the service but my request is not going in JSON format.
If I change the header to 'Content-Type': 'application/json', getting
XMLHttpRequest cannot load https://XXXX.XXXX.in/XXXXAPI/UserLogin.
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://170.11.0.61' is therefore not allowed access.
I don't know what is the reason for this error.
$.ajax({
url: BASE_URL + "UserLogin",
type: "POST",
xhrFields: {withCredentials: true},
data: {
"uname": uname,
"password": password
},
cache: false,
success: function (result, textStatus, request) {
console.log(result);
},
error: function (e) {
console.log("Error in login service call:"+JSON.stringify(e));
}
});
This jQuery is sending my request in the json format.
Try to pass headers like
headers: { 'Content-Type': 'application/json' }

Http request in angular send undefine values

** It turns out that the problem was at the server **
I'm trying to excute HTTP post request (from my angular client) to my server (node express). The server recive the request but the data is undefined.
Already tried to make this req by postman and it worked perfect there.
var req = {
method: 'POST',
url: _url +'/login',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: { user: 'someUser', password :'somePass' }
}
$http(req)
.then(function success(res){
...
}, function error(res){
...
});
You are sending JSON data and sending the header of x-www-form-urlencoded.
Change the content type to "application/json"
Like:
headers: {
'Content-Type': 'application/json'
}

AngularJS HTTP GET request returning cached data

In my AngularJS app I am sending HTTP GET request as below.
MyService.HttpReq("testUrl", "GET", null);
HttpReq Method is defined in a service and implemented as below:
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: postData,
headers: {
'Content-Type': 'application/json',
}
}).success(function(response)
{
console.log("Success: "+JSON.stringify(response));
}).error(function(data, status)
{
console.error("Error");
});
}
First of all is this the right way of sending HTTP request in AngularJS?
The problem that I am facing is, some times I get cached data as response and HTTP request is not hitting the server. what can be the issue?
UPDATE
As per the comment and answer I have updated my HTTP request code as below, but still getting same issue.
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: payload,
headers: {
'Content-Type': 'application/json',
'Cache-Control' : 'no-cache'
}
}).
then(
function(response)
{
var data = response.data;
console.log("Success: "+JSON.stringify(data));
},
function(response)
{
var data = response.data || "Request failed";
var status = response.status;
console.error("Error: "+JSON.stringify(data));
}
);
}
IE Browsers will catch ajax get requests even if we add cache control headers to the response. Only way i found to solve the issue is to add some random parameter to the request. Please make sure the api have no problem even if you send extra parameters
MyService.HttpReq("testUrl?ts=" + Date.now(), "GET", null);
Just add cache: false attribute to config object.
https://docs.angularjs.org/api/ng/service/$http#caching
Also you can add header: 'Cache-Control' : 'no-cache'

Resources