withCredentials oboe request - angularjs

I am currently working with a Neo4j graph database that offers REST url's for free. And I am trying to hook it up to a angular module that provides Oboe client side streaming: https://github.com/RonB/angular-oboe
I am trying to better understand how to add username:password credentials in my request header in an effort to transcribe this curl command
> curl --user username:password http://localhost:7474/auth/list
https://github.com/neo4j-contrib/authentication-extension
In the Usage section of the angular-oboe README, it outlines parameters for the request
$scope.myData = Oboe({
url: '/api/myData',
pattern: '{index}',
pagesize: 100
});
I have a hunch to add a line for withCredentials as listed on the Oboe repo
https://github.com/jimhigson/oboe.js-website/blob/master/content/api.md
oboe({
url: String,
method: String, // optional
headers: Object, // optional
body: String|Object, // optional
cached: Boolean, // optional
withCredentials: Boolean // optional, browser only
})
But I'm not sure where to put the username:password pair.
Any help you could offer would be greatly appreciated in collaboration.

The angular-oboe service passes all parameters to the Oboe function so you can specify a headers parameter. To make sure authentication is allowed on the request specify withCredentials: true.
Basic authentication can be achieved by:
.controller('StreamingCtrl', function($scope, Oboe) {
$scope.contacts = [];
// the contacts streamed
$scope.contacts = Oboe({
url: 'http://some.restfull.srv/contacts',
pattern: '{contactid}',
pagesize: 100,
withCredentials: true,
headers: {
// Base 64 encoded Basis authentication
Authorization: 'Basic ' + btoa('username:password')
}
});
})
The btoa function will Base 64 encode the username and password.
Edit:
The angular-oboe factory has been altered since the first answer and is returning a promise instead of the array of json objects.
This is how to use the latest version:
angular.module('MyApp')
.controller(['$scope', 'Oboe', function($scope, Oboe) {
$scope.myData = [];
Oboe({
url: '/api/myData',
pattern: '{index}',
withCredentials: true,
headers: {
Authentication: 'Basic ' + btoa('yourusername:yourpassword')
}
}).then(function() {
// finished loading
}, function(error) {
// handle errors
}, function(node) {
// node received
$scope.myData.push(node);
});
}]);

Related

Set one of the angular HTTP data variables to a boolean

Edit: Is this possibly an issue with the backend API? The data requests sent over $.param are always strings, correct? So they need to parse that stuff on their backend?
I am currently trying to send a post request to an API to register a user. One of the requirements is to accept terms and conditions and an age requirement, which it expects a boolean.
I believe the issue might be that the $http request is sending a STRING and not a boolean to the API backend and so it's rejecting it. How would I send a boolean through $http?
var apiCall = {
method: 'POST',
url: 'API_URL',
data: $.param({
'user[email]': username,
'user[password]': password,
'user[password_confirmation]':password,
'profile[age_acceptance]': ageAcceptance,
'profile[terms_acceptance]': termsAcceptance
}),
headers: {
'Accept': 'application/vnd.softswiss.v1+json',
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: function(data, headersGetter, status) {
console.log(data);
console.log(headersGetter(data));
}
}
var dataToPost = JSON.stringify( {
'user[email]': username,
'user[password]': password,
'user[password_confirmation]':password,
'profile[age_acceptance]': ageAcceptance,
'profile[terms_acceptance]': termsAcceptance
});
data: dataToPost,
headers: {.......,
.....
you have to stringy your parameters.
JSON.stringify(params)

Angular js how to pass data to delete service?

I am working in angular js on delete service api when passing data in service it is showing 400 bad request error.This is my js to call the service.
$scope.deleteUser = function(id){
var data = 'Id='+id;
DataService.deleteUser(data).then(function successCallback(response) {
console.log('deleted');
}, function errorCallback(response) {
console.log(response);
});
}
This is service js to delete users.
service.deleteUser = function(data){
var config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Auth-Token': 'mytoken'
}
};
return $http.delete(mainURL + '/users', data, config);
};
This is curl api request where i need to pass data:
curl -v -H "X-Auth-Token: mytoken" -X DELETE -F Id=665799088 http://<ipaddress>/users
The 2nd parameter to $http.delete is the config, so you need to pass the config object as the 2nd parameter and not data.
DELETE method type doesn't accept a Request body so you should not be passing the ID as data. Instead try this http://main_url/users?Id=id
So in your service use this
return $http.delete(mainURL + '/users?Id='+data, config);
Also check how you are passing the ID to your API. If you are passing ID as a query parameter then the above will work, but if you are passing it as a route parameter then the above URL won't work, but from your CURL expression I believe you are passing Id in the Query string and not as a route parameter.
According to documentation on $http service, delete method only accepts 2 parameters, url and config, meaning that your data is currently treated like config. You are most likely looking to pass some params options to your config object.
DataService.deleteUser(id).then(function successCallback(response) {
console.log('deleted');
}, function errorCallback(response) {
console.log(response);
});
And your service declaration should be more like.
service.deleteUser = function(id){
var config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Auth-Token': 'mytoken'
},
params : {
id : id
}
};
return $http.delete(mainURL + '/users', config);
};
Also keep in mind that a path looking like /users/id is more correct, if you are in charge of the API.

AngularJS 1.3 to 1.5 transformRequest broke, solution for my specific situation?

Long story short. I am really not an AngularJS guru. Our site upgraded from 1.3 to 1.5. This one thing is breaking.
We used to inject an HTTP header via transformRequest in a factory named 'api':
.factory('api', function($resource) {
function add_auth_header(data, headersGetter) {
var headers = headersGetter();
headers['Authorization'] = ('Basic ' + btoa(data.username +
':' + data.password));
}
// defining the endpoints.
return {
auth: $resource('/api/v1/auth/', {}, {
login: {method: 'POST', transformRequest: add_auth_header},
logout: {method: 'DELETE'},
}),
Later on in the same file, this is called like so:
.service('auth', function($cookies, $rootScope, api) {
this.user = null;
this.login = function(credentials) {
var log = api.auth.login(credentials);
log.$promise.then(function(data){
// on good username and password
this.user = data;
});
As you can see, it calls api.auth.login with the credentials. I have verified that the transform request is being called, the headers are being fetched properly by headersGetter(), and that hanging the headers[] object no longer changes it like it used to in 1.3. Fiddler verifies that the request no longer has an Authorization header in it like it did in 1.3, and the Django server that gets the request also agrees.
I've read in a few places that the transformRequest functionality 'broke' in 1.4, but those posts have always been in the context of making an $http request, not providing an api service through a factory, and haven't made much sense to an AngularJS newb like me. I have no idea where I would start changing how Authorization is injected.
Can anyone point me the right way?
If anyone else is still facing this, the change was under breaking changes in the changelog for 1.4.
I feel the fix speaks for itself. Note that the function add_auth_header is not invoked but rather is passed.
.factory('api', function($resource) {
function add_auth_header(data) {
// as per HTTP authentication spec [1], credentials must be
// encoded in base64. Lets use window.btoa [2]
return 'Basic ' + btoa(data.data.username + ':' + data.data.password);
}
// defining the endpoints.
return {
auth: $resource('/api/v1/auth/', {}, {
login: {method: 'POST', headers: { 'Authorization': add_auth_header }},
logout: {method: 'DELETE'},
}),

add config in angular resource

I am using http-auth-interceptor for authentication. In http-auth-interceptor, I use the following way to login:
var data = 'username=' + encodeURIComponent(user.userId) + '&password=' + encodeURIComponent(user.password);
$http.post('api/authenticate', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
ignoreAuthModule: 'ignoreAuthModule'
})
ignoreAuthModule is used to tell ignoreAuthModule that this login method will be ignored by the auth interceptor.
Now, I have some request with $resource, like:
.factory('SomeDataService', function ($resource) {
return $resource('api/some/data', {}, {
'get': { method: 'GET'}
});
})
I want SomeDataService.get() is also ignored by the auth interceptors, because I need to control the 401 error by myself.
So, my question is, is there any way for ngResource that I can set config like that in $http.
[update based on comment]
I have listened the login-required event:
$rootScope.$on('event:auth-loginRequired', function (rejection) {
$log.log(rejection);
// I need to get the request url and for some specific url, need to do something.
$rootScope.loginPopup();
});
But the 'rejection' parameter has no context data of request I need. I need to get the request url and check, for some specified url, I need to do something.
After checking the document of ngResource, I got the solution as below:
.factory('SomeDataService', function ($resource) {
return $resource('api/some/data', {}, {
'get': { method: 'GET', ignoreAuthModule: 'ignoreAuthModule'}
});
})
Just add the config item as above. It will be equivalent ad:
$http.post('api/some/data', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
ignoreAuthModule: 'ignoreAuthModule'
})
ngResource module is build on top of $http.Hence it is not possible to configure all the stuffs you can do with $http in $resource.I think the below link will be guide you to have a clear understanding on $http and $resource

How can you test for http config options in AngularJS?

In this service method I want to test for the presence of the skipAuthorization setting.
var register = function (registration) {
logout();
return $http({
url: apiUrl + 'api/account/register',
method: 'POST',
data: registration,
skipAuthorization: true
});
};
Using $httpBackend, I can inspect the data and the headers, but I can't find any documentation related to the optional config object.
Thanks!
UPDATE:
I'm not thrilled with the solution below, but it does test the scenario in a round-about way.
it('should flag the interceptor to skip authorization', function () {
spyOn(my_store, 'get').and.returnValue('foo');
service.register();
http.expectPOST(url, undefined, function (headers) {
//If we don't skip authorization, this header would be "Bearer foo"
return headers['Authorization'] === undefined;
});
http.flush();
});
This works because if I don't set skipAuthorization to true, I will see a bearer token on the request headers. It relies on the fact that my interceptor pulls the token out of local storage, which I have mocked with a Jasmine spy (my_store).

Resources