Not able to pass custom headers into Backbone's fetch - backbone.js

ers.
I am trying to implement my custom collection where I overwrite fetch method. Later I will use this collection to extend my Backbone collections.
var BaseCollection = Backbone.Collection.extend({
fetch: function (options) {
options = options || {};
if (!options.headers) {
options.headers = {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization' : "Basic: user:password"
};
}
options.reset = true;
console.log('I am extended fetch method');
return Backbone.Collection.prototype.fetch.call(this, options);
}
});
var ShipsCollection = BaseCollection.extend({
url: 'http://localhost:3000/v1/ships',
model: Ship
});
But when I call fetch for my collection I can not see headers were sent to the server:
var shipsCollection = new ShipsCollection();
shipsCollection.fetch();
How can I extend fetch to be able send custome headers ? I do not want to overwrite sync.

As you can see from the fiddle shared by #nikoshr in comments, the code seems to work.
However, your code won't work in case options.headers exist. I suggest modifying the code as follows:
fetch: function(options) {
options = options || {};
var custom = {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': "Basic: user:password"
};
options.headers = options.headers ? _.extend(options.headers, custom) : custom;
options.reset = true;
return Backbone.Collection.prototype.fetch.call(this, options);
}

In my case it was a AdBlock plugin. When I removed it everything went fine.

Related

Connecting to bank account with OAuth2.0 and Google App Scripts

My bank offers to connect to their APIs using OAuth2. I want to create an App Script to autmatically write my transactions to google docs. This is my first time using OAuth and I can't seem to get the access token. Below I have pasted my attempt at receiving an access token, but the site refuses my request. Below my code example are two code examples (one for Node and one for Python) which are provided by the bank. Are there any obvious mistakes that I don't see?
My code:
function get_auth_token() {
var identityServerUrl = "https://auth.sbanken.no/identityserver/connect/token"; // access token endpoint
var clientId = '...'
var secret = '...'
var basicAuth = Utilities.base64Encode(encodeURIComponent(clientId) + ":" + encodeURIComponent(secret)); // create basicAuth header value according to Oauth 2.0 standard
var response = UrlFetchApp.fetch(identityServerUrl, {
headers: {
'Accept': 'application/json',
'customerId' : clientId,
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + basicAuth}
});
}
Node code from the bank:
exports.getAccessToken = () => {
var identityServerUrl = "https://auth.sbanken.no/identityserver/connect/token"; // access token
endpoint
var clientId = credentials.clientid; // application key received from API Beta in the internetbank
var secret = credentials.secret; // password received from API Beta in the internetbank
var basicAuth = btoa(encodeURIComponent(clientId) + ":" + encodeURIComponent(secret)); // create basicAuth header value according to Oauth 2.0 standard
var accessToken;
// request accessToken (the basic auth data is put on the request header prior to sending the request)
let response;
var promise = new Promise(function (resolve, reject) {
request
.post(identityServerUrl)
.send('grant_type=client_credentials')
.set('Authorization', "Basic "+basicAuth)
.set('Accept', 'application/json')
.set('customerId', credentials.userid)
.end(function(err, res){
if (err || !res.ok) {
console.log(err);
reject();
} else {
console.log('yay got ' + JSON.stringify(res.body));
resolve(res.body);
}
});
});
Python code from the bank:
CLIENT_ID = '' # Get from https://secure.sbanken.no/Personal/ApiBeta/Info/
SECRET = '' # Get this from https://secure.sbanken.no/Personal/ApiBeta/Info/
AUTH_URL = 'https://auth.sbanken.no/identityserver/connect/token'
ACCOUNTS_URL = 'https://api.sbanken.no/exec.bank/api/v1/accounts'
CUSTOMER_ID = '' # Your own personnummer
def get_auth_token(auth_url, client_id, secret):
headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
}
body = {'grant_type': 'client_credentials'}
urlencoded_client_id = urllib.quote(client_id)
urlencoded_secret = urllib.quote(secret)
auth_string_to_be_b64encoded = '{}:{}'.format(
urlencoded_client_id, urlencoded_secret)
b64encoded_auth_string = base64.b64encode(auth_string_to_be_b64encoded)
headers['Authorization'] = 'Basic {}'.format(b64encoded_auth_string)
r = requests.post(url=auth_url, headers=headers, data=body)
auth_token = r.json()['access_token']
return auth_token
From the code samples, I'd bet that you need to pass grant_type=client_credentials as part of the request. There are two ways you can do this:
Add it to the URL https://auth.sbanken.no/identityserver/connect/token?grant_type=client_credentials
Include it as the payload of the UrlFetchApp.fetch() request (this would be the more "correct" approach):
var response = UrlFetchApp.fetch(identityServerUrl, {
headers: {
'Accept': 'application/json',
'customerId' : clientId,
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + basicAuth
},
payload: 'grant_type=client_credential'
});
Unfortunately, I can't verify if that's all you'll need to do to make it work, but it should get you going in the right direction. Also, I'd really recommend you try to configure this through Google's OAuth2 library, although it isn't the most straight-forward to implement.
The answer can be found in Diego's post, but I also made some other changes to the code:
var headers = {
'Authorization': 'Basic ' + basicAuth,
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
};
var options = {
"method" : "get",
"headers" : headers,
"payload" : {'grant_type': 'client_credentials'},
};
var response = UrlFetchApp.fetch(identityServerUrl, options);

Angular2 http.put shows two requests in console?

One of the requests is from zone.js and the other is from "other"
saveContact(contact: Contact) {
let body = contact;
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.put(`http://localhost:8082/business/${contact.businessId}/contacts/${contact.contactId}`, body, headers)
.map(this.returnSuccess)
.catch(this.handleError);
}
Here is the Network:
Why am I getting two requests when I had only made one?

What does 'Content-Type': 'application/x-www-form-urlencoded do in http post method

I still don't know how to make a correct http post method in angular 2, I did as they show on their official website.
I have this function createNewPlaylist in my api.service.ts
createNewPlaylist(stDate: string, etDate: string, playlistTitle: string, shortTitle: string): Observable<any> {
/**some code here **//
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(`https://cmsapi-dev.b2c.on.aol.com/v1.0/cms/playlists/${this.g_app}/${this.g_region}?trustedUserId=myuserid`,
JSON.stringify({
name: playlistTitle,
shortName: shortTitle,
}), options);
}
And I have this function in my component
createNewPlaylist(stDate: string, etDate: string, playlistTitle: string, shortTitle: string):any {
this.apiService.createNewPlaylist(stDate, etDate, playlistTitle, shortTitle)
.map(res => console.log(res))
.subscribe(
data => console.log(data),
error => console.log(error)
);
If i use the browser, enter the url directly (https://mydomain/v1.0/cms/playlists/aolon/us?name=asd&shortName=lalalal&method=POST&trustedUserId=myuserid), it will generate correct respond.
But my console get an error when I do it normally,
{"response":{"statusCode":478,"statusText":"Bad argument - name"}}
Any ideas?
Update: I changed my code to this and it works, can someone explain to me?
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
return this.http.post(`https://cmsapi-dev.b2c.on.aol.com/v1.0/cms/playlists/${this.g_app}/${this.g_region}/?trustedUserId=myuserid`,
`name=${playlistTitle}&shortTitle=${shortTitle}`, options )
I think that you need to set correctly the Content-Type header for your POST request:
implicitly (from RC2)
return this.http.post(`https://cmsapi-dev.b2c.on.aol.com/v1.0/cms/playlists/${this.g_app}/${this.g_region}?trustedUserId=myuserid`,
{
name: playlistTitle,
shortName: shortTitle,
});
explicitly
let headers = new Headers();
headers.append('Content-Type', 'application/json'); // <------
return this.http.post(`https://cmsapi-dev.b2c.on.aol.com/v1.0/cms/playlists/${this.g_app}/${this.g_region}?trustedUserId=myuserid`,
JSON.stringify({
name: playlistTitle,
shortName: shortTitle,
}), { headers }); // <-------

POST a JSON array with ANGULARJS $resource

I need to do send a json array to a restful api from my angularjs application. I am using ngresources to do this.
Since now, I have been abled to post and put single object with no problem, but now I need to send an array of objects and I can't.
I tried to do the call from a external rest application and it works fine but it's impossible from my angular application. I have trie to parse the objet with JSON.stringify but stills not working. I set the header 'Content-Type': 'application/json', as well on the $resources.
This is how I do the negresource:
.factory('AddSignosClinicos', function ($resource) {
return $resource(dondeapuntar + "/Rest/Pacientedatossignosclinicos.svc/pACIENTEDATOSSIGNOSCLINICOSList/Add", {}, {
create: { method: "POST", headers: { 'Content-Type': 'application/json', params: {} } }
});
})
And this is how I call the function:
var objeto = JSON.stringify(SignosClinicosGuardar);
var signosClinicosService = new AddSignosClinicos(objeto);
signosClinicosService.$create().then(function () {});
I made a console.log of objeto, and is a proper json array.
Any idea?
Thank you very much
EDIT
I have tried $http component for the post request, and it worked! I donĀ“t understand why is not working with ngResources, this is my code for $http:
$http({
url: 'http://localhost:1046/Rest/Pacientedatossignosclinicos.svc/pACIENTEDATOSSIGNOSCLINICOSList/Add',
method: "POST",
data: SignosClinicosGuardar,
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
});
To post an array of objects you'll need to add the option isArray: true to your $resource:
.factory('AddSignosClinicos', function ($resource) {
return $resource(
"url-string-here",
{},
{
create: {
method: "POST",
isArray: true
}
}
);
})
Calling the new create function would look something like this:
//some list of your object instances
var array_of_objects = ...
var saved_objects = AddSignosClinicos.create(
array_of_objects
);
saved_objects.$promise.then(function() {
...
});
Note, the create vs $create, there's no $.
See the Angular documentation on $resource

Custom HTTP headers always get added under "Access-Control-Request-Headers"

I am new to Angular JS. I am writing a simple client to pull data from a HTTP endpoint.
All headers I set are sent over the wire under the header Access-Control-Request-Headers, but not as actual HTTP headers in the request.
delete $http.defaults.headers.common['X-Requested-With'];
var config = {
headers: {
'customHeader1': 'value1'
}
};
$http.defaults.headers.get = {
'customHeader2': 'value2'
};
$http.get("http://localhost:8280/abc",config).success(function(data) {
// alert(data);
$scope.names = data.records;
}).error(function(response, data, status, header) {
alert(status);
});
Could you try that suggestion from the official Angular JS documentation:
To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis, Use the headers property, setting the desired header to undefined. For example:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
$http(req).then(function(){...}, function(){...});

Resources