How to hit a rest service with authentication in angularjs? - angularjs

This is my code but i am getting unauthorised(401) error,i have used CORS filter on server side but still i am not able to hit the API
var authdata = Base64.encode("username:password");
var data={};
var config = {
headers : {
'Content-Type': 'application/json;charset=utf-8;',
'Authorization' : 'Basic'+ authdata,
'Accept':'application/json'
}
};
function fetchAllUsers(){
ViewRecord.fetchAllUsers(REST_SERVICE_URI,data,config)
.then(
function(d) {
self.users = d;
},
function(errResponse){
console.error('Error while fetching Users');
}
);
}

There needs to be a space after Basic in the authorization header.
// Bad
'Authorization' : 'Basic'+ authdata,
// Good
'Authorization' : 'Basic '+ authdata,

Related

AngularJS: Http header

I am newbie of angularJS. I want to add header in my http request but i am not understanding how? so far i've written this code.
Original code without header:
function saveUser(user, $http) {
var token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjYxLCJpc3MiOiJodHRwOlwvXC8zNC4yMDQuMjIyLjExM1wvYXBpXC91c2VycyIsImlhdCI6MTQ5NTE4MDY3MCwiZXhwIjoxNDk1MTg0MjcwLCJuYmYiOjE0OTUxODA2NzAsImp0aSI6IkdkNXdUSmZQMDRhcjc2UWIifQ.dKGZTysAibFbtruvSI7GwFV61kh43CX22g8-sRV9roQ";
var url = __apiRoot + "/users/" + user.id;
var dataObj = {
payload: JSON.stringify(user),
_method: "PUT",
}
return $http.post(url, dataObj);
}
Now i am adding header to it, the code becomes like this:
function saveUser(user, $http) {
var token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjYxLCJpc3MiOiJodHRwOlwvXC8zNC4yMDQuMjIyLjExM1wvYXBpXC91c2VycyIsImlhdCI6MTQ5NTE4MDY3MCwiZXhwIjoxNDk1MTg0MjcwLCJuYmYiOjE0OTUxODA2NzAsImp0aSI6IkdkNXdUSmZQMDRhcjc2UWIifQ.dKGZTysAibFbtruvSI7GwFV61kh43CX22g8-sRV9roQ";
var url = __apiRoot + "/users/" + user.id;
var dataObj = {
payload: JSON.stringify(user),
_method: "PUT",
}
return $http({headers: {
'Authorization': token
}}).post(url, dataObj);
}
By adding header, i am getting this error:
angular.js:14525 Error: [$http:badreq] Http request configuration url
must be a string or a $sce trusted object. Received: undefined
You're using the wrong syntax. Take a look at the angular documentation for $http here.
Your code should look like this:
$http({
method: 'POST',
url: __apiRoot + "/users/" + user.id,
data: JSON.stringify(user)
headers: {
'Authorization': token
}
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});

ngResource add header to request not working

I am trying to send token in the header but it is not working, what is the way of sending token in the header? Or what is the problem in my code?
return $q(function(resolve , reject){
var token = StorageService.getToken();
if(!token)
console.log('no token')
var resource = $resource(usersAPI.profile,null,
{
query: {
method: 'GET',
header: {
'Authorization': 'Bearer ' + token
}
}
})
var profile = resource.query(function(result){
console.log(result)
},function(err){
console.log('error',err)
})
resolve(profile)
})

CORS error with Facebook callback function

I have the following code:
app.js:
var passport = require('passport')
, FacebookStrategy = require('passport-facebook').Strategy
, ...
passport.serializeUser(function(user, done) {
console.log('serializing user')
done(null, user);
})
passport.deserializeUser(function(obj, done) {
console.log('deserializeUser')
done(null, obj)
})
passport.use(new FacebookStrategy({
clientID: FBAPP.id,
clientSecret: FBAPP.secret,
callbackURL:
"http://www.mylocal.com:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
return done(null, profile)
})
}
))
app.get('/auth/facebook', passport.authenticate('facebook',
{ scope: ['email, user_likes, user_photos, publish_actions'] }))
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect: '/loginsuccess', failureRedirect : '/loginfail' }))
app.get('loginsuccess', function(req, res) {
console.log('Login success')
res.send(200, 'ok')
})
app.get('/loginfail', function(req, res) {
console.log('Login error')
res.send(401, 'error')
})
The angular part:
factory('FacebookFactory', ['$http', '$q', function($http, $q) {
var get = function() {
var deferred = $q.defer();
$http({method: 'GET', url: '/auth/facebook'}).
success(function(data, status, headers, config) {
deferred.resolve(data);
}).
error(function(data, status, headers, config) {
deferred.reject(data);
});
return deferred.promise;
};
return {
get: get
};
}])
I get always this error and did several attempts but no success.
XMLHttpRequest cannot load https://www.facebook.com/dialog/oauth?
response_type=code&redirect_uri=http%…
user_likes%2C%20user_photos%2C%20publish_actions&client_id=xxxxxxxxxxx.
No 'Access-Control-Allow-Origin' header
is present on the requested resource. Origin '[basic
links]http://www.mylocal.com:3000' is therefore
not allowed access.
Anyone any idea? I did try it solely in angular but then it does not work in Safari but in Chrome and FF it works perfectly.
www.mylocal.com:3000 = localhost:3000
You will not find a solution with client side languages as this constitutes a cross-origin request which could be used as a malicious attack. So basically the Facebook endpoint would need to have a Access-Control-Allow-Origin header block set and I don't think they will do that anytime soon. I use APIs alot and frequently have to have theses headers set in my endpoint so my clients can connect from localhost or dev urls:
if (isset($_SERVER['HTTP_ORIGIN'])):
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
endif;
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS'):
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])):
header('Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT');
endif;
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])):
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
endif;
exit(0);
endif;
You could also try this in your $http broker:
var promise = $http({
method: 'POST',
url: 'url_to_api',
data: params,
headers: {
'Access-Control-Allow-Origin': true,
'Content-Type': 'application/json'
}
}).success(function (data, status, headers, config) {
return data;
});
I have an Angular app with express on the backend. When I clicked on a button with this HTML:
<input type="button" ng-click="socialLogIn('facebook')" class="modal-input" value="Sign in with Facebook">
It gave me a CORS error:
$scope.socialLogIn = function (social) {
return $http.get ('/auth/'+social).success (function (data) {
auth.saveToken (data.token); // write data to local storage
});
Problem is, I wanted to get the token back so I could save it in localStorage. I did solve it, but the solution is round-about. In the socialLogIn function, I opened a new window:
$scope.socialLogIn = function (social) {
var url = 'http://' + $window.location.host + '/auth/' + social;
$window.open(url);
};
In the express backend, after I got my 'stuff' from Facebook or Google and I created the token, I sent back some code that saved the token, reloaded the parent window and closed itself:
function loginReturn (res, token) {
var returnString = '' +
'<!DOCTYPE html>\n' +
'<html>\n' +
'<head>\n' +
'<meta charset="UTF-8">\n' +
'<title>Login</title>\n' +
'</head>\n' +
'<body>\n' +
'<script type="text/javascript">\n' +
'window.localStorage[\'token\'] = \''+token+'\';\n' +
'window.opener.location.reload(false);\n' +
'window.close();\n' +
'</script>\n' +
'</body>\n' +
'</html>';
res.send(returnString);
};

how to get headers from response in angularjs

This is my sample, i'm not get response headers, it returns undefined
I'm trying to get custom response headers like reponse.header['X-auth-token'] but it returns undefined
I'm new to angular js, Please share your idea
Thanks in advance
//I'm trying to get custom response headers here (using alert(response.headers);)
Controller
UIAppRoute.controller('test', ['$scope', 'checkStatus', function($scope, checkStatus) {
$scope.data = {};
checkStatus.query(function(response) {
alert(response.headers);
angular.forEach(response, function (item) {
alert("resp2"+ item);
});
$scope.data.resp = response;
});
}]);
// sending request to server
service
-------
UIAppResource.factory('checkStatus', function($resource){
var auth = Base64.encode("abcde:abcde");
return $resource(baseURL + "status", {},
{
'query': {
method: 'GET',
headers: {
'Accept':'application/json',
'Content-Type':'application/json',
'Authorization': 'Basic '+ auth,
'Access-Control-Allow-Headers' : 'Origin, X-Requested-With, Content-Type, Accept'
},
isArray: false
}
}
)
how to get headers from response in angularjs ?
Please share your idea
Thanks in advance
response.headers is a function an not a map, so you have to call it instead of accessing it via a key.
response.headers('headerName') should give you the respective header.
See also http://code.angularjs.org/1.2.16/docs/api/ng/service/$http
For $resource see http://code.angularjs.org/1.2.16/docs/api/ngResource/service/$resource
var User = $resource('/user/:userId', {userId:'#id'});
User.get({userId:123}, function(u, headers){
alert(headers('X-Internal-Auth-Token'))
});
});
the first param of function is the returned data, the second param is headers;
so you should write as follow:
checkStatus.query(function(data,headers) {
console.log(headers('xxxx'));
});

AngularJS withCredentials

I've been working on an AngularJS project which has to send AJAX calls to an restfull webservice. This webservice is on another domain so I had to enable cors on the server. I did this by setting these headers:
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "http://localhost:8000");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
I'm able to send AJAX requests from AngularJS to the backend but I'm facing a problem when I try to get an attribute of a session. I believe this is because the sessionid cookie doesn't get send to the backend.
I was able to fix this in jQuery by setting withCredentials to true.
$("#login").click(function() {
$.ajax({
url: "http://localhost:8080/api/login",
data : '{"identifier" : "admin", "password" : "admin"}',
contentType : 'application/json',
type : 'POST',
xhrFields: {
withCredentials: true
},
success: function(data) {
console.log(data);
},
error: function(data) {
console.log(data);
}
})
});
$("#check").click(function() {
$.ajax({
url: "http://localhost:8080/api/ping",
method: "GET",
xhrFields: {
withCredentials: true
},
success: function(data) {
console.log(data);
}
})
});
The problem that I'm facing is that I can't get this to work in AngularJS with the $http service. I tried it like this:
$http.post("http://localhost:8080/api/login", $scope.credentials, {withCredentials : true}).
success(function(data) {
$location.path('/');
console.log(data);
}).
error(function(data, error) {
console.log(error);
});
Can anyone tell me what I'm doing wrong?
You should pass a configuration object, like so
$http.post(url, {withCredentials: true, ...})
or in older versions:
$http({withCredentials: true, ...}).post(...)
See also your other question.
In your app config function add this :
$httpProvider.defaults.withCredentials = true;
It will append this header for all your requests.
Dont forget to inject $httpProvider
EDIT : 2015-07-29
Here is another solution :
HttpIntercepter can be used for adding common headers as well as common parameters.
Add this in your config :
$httpProvider.interceptors.push('UtimfHttpIntercepter');
and create factory with name UtimfHttpIntercepter
angular.module('utimf.services', [])
.factory('UtimfHttpIntercepter', UtimfHttpIntercepter)
UtimfHttpIntercepter.$inject = ['$q'];
function UtimfHttpIntercepter($q) {
var authFactory = {};
var _request = function (config) {
config.headers = config.headers || {}; // change/add hearders
config.data = config.data || {}; // change/add post data
config.params = config.params || {}; //change/add querystring params
return config || $q.when(config);
}
var _requestError = function (rejection) {
// handle if there is a request error
return $q.reject(rejection);
}
var _response = function(response){
// handle your response
return response || $q.when(response);
}
var _responseError = function (rejection) {
// handle if there is a request error
return $q.reject(rejection);
}
authFactory.request = _request;
authFactory.requestError = _requestError;
authFactory.response = _response;
authFactory.responseError = _responseError;
return authFactory;
}
Clarification:
$http.post(url, {withCredentials: true, ...})
should be
$http.post(url, data, {withCredentials: true, ...})
as per https://docs.angularjs.org/api/ng/service/$http

Resources