400 Error on AJAX Call to Twitter - javascript

I'm working on a web page that lets you search for twitter users in your area. You enter a name in the search box and it returns users with that name within 50 miles of the city (the city is always the same).
I was having trouble authenticating, and I found oauth.io. I used that to authenticate and it seems to be working. But when I do a search, my request to Twitter returns as a 400 bad request error. I'm not sure what I'm doing wrong. I've looked at the oauth.io documentation but couldn't find anything.
Here is the part of the code that gets the value of what the user entered into the form field:
// Click function
$('.user-getter').submit(function(event) {
// prevent form refresh
event.preventDefault();
// zero out results if previous search has run
$('.user-results').html('');
// Get the values of what the person entered in search
var query = $(this).find("input[name='user_search']").val();
// Run function to send API request to Twitter
getUser(query);
}); // end click function
Here is the part of the code that calls the authorization and then sends the ajax request:
var getUser = function(query) {
OAuth.initialize('oMQua1CuWerqGKRwqVkzDx5uijo')
OAuth.popup('twitter').done(function(twitterData) {
$.ajax({
type: "GET",
url: "https://api.twitter.com/1.1/users/search.json?&geocode=42.94003620000001,-78.8677924,50mi&q=" + query,
dataType: "jsonp"
});
console.log( "Data Saved: " + twitterData ); // can see in inspector tab under Network
}); // end oAuth popup
};
Right now, I just want to see the result in console.log.

To make a request to Twitter API using OAuth.io you have to use the OAuth.io Javascript SDK instead of directly $.ajax (the OAuth.io Javascript SDK use the syntaxe of $.ajax behind the scene)
OAuth.initialize('oMQua1CuWerqGKRwqVkzDx5uijo')
OAuth.popup('twitter').done(function(twitterData) {
twitterData.get('/1.1/users/search.json', {
data: {
q: query
}
}).done(function(search) {
//result of the search here
console.log(search);
}).fail(function(error) {
//error management here
});
})
The SDK does all the hard things for you transparently: proxy the HTTP request, inject all the needed OAuth credentials (oauth_token, oauth_token_secret, signature, nonce, timestamp etc..)
Take a look to this jsfiddles: http://jsfiddle.net/uz76E/10/
I hope that helps,

Related

Google translation Oauth2.0 from browser

I am creating a simple web page, that make use of the Google Translation Service.
The page has a field, to receive the input from the user and a button to trigger the call to the Translation API. It returns the result translation to the user.
I've successfully done the flow above using Ajax requests, but the access token
is hard-coded into my method and I want to change that to a call that gets sent whenever the token expires (currently I have to request a new token using the Google CLI and replace it in my code).
I have a very basic knowledge of Oauth2.0 and I've read the Google Documentation but couldn't find a part of it that would tell me the endpoint to call to get an access token from the client-side.
Could someone point me in the right direction, please?
Here is my code:
HTML:
<form id="translate_form">
<input id="input" />
<button id="translate_button">Translate</button>
</form>
Javascript
$("#translate_form").submit(function () {
var text = $("#input").val()
sendTranslationRequest(text);
return false;
})
function sendTranslationRequest(inputText) {
var requestBody = {
q: inputText,
source: "en",
target: "fr",
format: 'text'
}
translationAjaxRequest(requestBody);
}
function translationAjaxRequest(requestBody) {
var access_token = [access_token]
$.ajax({
url: "https://translation.googleapis.com/language/translate/v2",
method: "POST",
contentType: "application/json",
beforeSend: function (request) {
request.setRequestHeader("Authorization", "Bearer " + access_token)
},
data: JSON.stringify(requestBody),
success: function (response) {
var translatedText = response.data.translations[0].translatedText
alert(translatedText)
},
error: function () {
console.log("An error occurred on the request:", response)
}
});
}
The relevant endpoints to get an access token and refresh it are:
https://accounts.google.com/o/oauth2/v2/auth
https://www.googleapis.com/oauth2/v4/token
However, you’ll need to perform several steps in order to get an access token and a refresh token. You may want to review this guide on Using OAuth2.0 for Web Server Applications. It will walk you through the prerequisites, obtaining an access token and refreshing your token.
Alternatively, you may use an API Key. Just be mindful of the recommendations on how to secure it, since a stolen API Key may be used to generate calls that would be charged directly to your billing account.

AWS API Call with Authorization Header ( session.getIdToken().getJwtToken() )

I Have a WebPage That USE AWS API Gateway using AWS-Cognito Authentication. Most of the Buttons in Web Page Call Api and send or Retrieve data. This is the Code I Use Under Every Button Click
getAuthenticateUser().getSession(function(err,session){
if (err) {
console.log("Error"+err);
return;
}
if(session.isValid())
{
$.ajax({
url: URL,
headers:
{
'Authorization':session.getIdToken().getJwtToken(),
'Content-Type':'application/json'
},
method: 'GET',
dataType: 'json',
success: function(data){
// Execute Function Need to Execute on Success
}
,
error: function (xhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
if(!session.isValid())
{
console.log("Session is not valid..!");
//Please Login to Continue
}
});
This is Working Fine without Issue.But the Problem is It take Some Time to Execute it Everytime and Feeles like every time it Gives a New Session for Each call even Previous Session is not Expired. How can I Use get new Session Only when it Expired and if Previous Session is not Expired just check the validity of it globally and get a new Authorization Header Only I need..?
Because In My Code Once User Press One Button and Send Data id same User press another button after 30 sec i'm getting new session again right ..? it really gives me really bad on web site Performance.
Any Idea How to Solve this ..?
this my getAuthenticationUser() Code
function getAuthenticateUser()
{
return userPool.getCurrentUser();
}
and this my Global Variable in that Javascript page
var poolData = {
UserPoolId : 'usXXXXXXXXXXOv3jSL',
ClientId : 'XXXXXXXXXXka8g'
};
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
getSession() does not create a new session if the current session is valid.
If the current session is either null or invalid, it tries to refresh the session (using the refresh token) to get the ID token that is necessary to successfully complete the HTTP request using the Authorization header. Otherwise, it throws an error requesting to authenticate.
You can see what getSession() exactly does by taking a look at the CognitoUser class definition. (currently on line 1016.)

getting gmail Contacts

I am trying to get g mail contacts ,with oauth google plus api javascript i am to get his profile, but unfortunately i am not able to get all email of contacts,but i mention every thing correct in scope and all,
can any one suggest me how can i get gmail contacts.
I am using below js :
https://apis.google.com/js/client.js
i wrote bellow code to get contact emails
var authParams = gapi.auth.getToken(); // from Google oAuth
authParams.alt = 'json';
$.ajax({
url: 'https://www.google.com/m8/feeds/contacts/default/full',
dataType: 'jsonp',
data: authParams,
success: function(text) {
alert("text?????????"+JSON.stringify(text.feed));
}
});
The Contacts API has a hard limit to the number of results it can return at a time even if you explicitly request all possible results. If the requested feed has more fields than can be returned in a single response, the API truncates the feed and adds a "Next" link that allows you to request the rest of the response.
Source
So you have to take the response, get the Next link from it, and make another request to get additional contacts.

I dont understand how to implement the Deleting Requests in request dialog

I have read the document here
but I don't understand how should I implement it right.
In my facebook app I use apprequests from JS api like this:
function newInvite() {
var msg = document.getElementById('msg_look_id').value;
var receiverUserIds = FB.ui({
method: 'apprequests',
message: msg,
title: "Select friends to send your gift",
},
function (response) {
alert("IDS : " + response.request_ids);
});
//http://developers.facebook.com/docs/reference/dialogs/requests/
}
then the user see the request in its app request icon (with the red numbers )
the user click it , but then how do I implement the delete request ?
When the user arrives at your app’s canvas page following a request, there is a parameter called request_ids passed to your app.
Since Facebook calls apps in the iframe using the HTTP method POST, I guess this is also a POST parameter (although it is not explicitly mentioned in the docs). That means you have no access to it using pure client-side JavaScript; you have to use a server-side script to get the content of this parameter.

AD FS 2.0 Authentication and AJAX

I have a web site that is trying to call an MVC controller action on another web site. These sites are both setup as relying party trusts in AD FS 2.0. Everything authenticates and works fine when opening pages in the browser window between the two sites. However, when trying to call a controller action from JavaScript using the jQuery AJAX method it always fails. Here is a code snippet of what I'm trying to do...
$.ajax({
url: "relyingPartySite/Controller/Action",
data: { foobar },
dataType: "json",
type: "POST",
async: false,
cache: false,
success: function (data) {
// do something here
},
error: function (data, status) {
alert(status);
}
});
The issue is that AD FS uses JavaScript to post a hidden html form to the relying party.
When tracing with Fiddler I can see it get to the AD FS site and return this html form which should post and redirect to the controller action authenticated. The problem is this form is coming back as the result of the ajax request and obviously going to fail with a parser error since the ajax request expects json from the controller action. It seems like this would be a common scenario, so what is the proper way to communicate with AD FS from AJAX and handle this redirection?
You have two options.
More info here.
The first is to share a session cookie between an entry application (one that is HTML based) and your API solutions. You configure both applications to use the same WIF cookie. This only works if both applications are on the same root domain.
See the above post or this stackoverflow question.
The other option is to disable the passiveRedirect for AJAX requests (as Gutek's answer). This will return a http status code of 401 which you can handle in Javascript.
When you detect the 401, you load a dummy page (or a "Authenticating" dialog which could double as a login dialog if credentials need to be given again) in an iFrame. When the iFrame has completed you then attempt the call again. This time the session cookie will be present on the call and it should succeed.
//Requires Jquery 1.9+
var webAPIHtmlPage = "http://webapi.somedomain/preauth.html"
function authenticate() {
return $.Deferred(function (d) {
//Potentially could make this into a little popup layer
//that shows we are authenticating, and allows for re-authentication if needed
var iFrame = $("<iframe></iframe>");
iFrame.hide();
iFrame.appendTo("body");
iFrame.attr('src', webAPIHtmlPage);
iFrame.load(function () {
iFrame.remove();
d.resolve();
});
});
};
function makeCall() {
return $.getJSON(uri)
.then(function(data) {
return $.Deferred(function(d) { d.resolve(data); });
},
function(error) {
if (error.status == 401) {
//Authenticating,
//TODO:should add a check to prevnet infinite loop
return authenticate().then(function() {
//Making the call again
return makeCall();
});
} else {
return $.Deferred(function(d) {
d.reject(error);
});
}
});
}
If you do not want to receive HTML with the link you can handle AuthorizationFailed on WSFederationAuthenticationModule and set RedirectToIdentityProvider to false on Ajax calls only.
for example:
FederatedAuthentication.WSFederationAuthenticationModule.AuthorizationFailed += (sender, e) =>
{
if (Context.Request.RequestContext.HttpContext.Request.IsAjaxRequest())
{
e.RedirectToIdentityProvider = false;
}
};
This with Authorize attribute will return you status code 401 and if you want to have something different, then you can implement own Authorize attribute and write special code on Ajax Request.
In the project which I currently work with, we had the same issue with SAML token expiration on the clientside and causing issues with ajax calls. In our particular case we needed all requests to be enqueud after the first 401 is encountered and after successful authentication all of them could be resent. The authentication uses the iframe solution suggested by Adam Mills, but also goes a little further in case user credentials need to be entered, which is done by displaying a dialog informing the user to login on an external view (since ADFS does not allow displaying login page in an iframe atleast not default configuration) during which waiting request are waiting to be finished but the user needs to login on from an external page. The waiting requests can also be rejected if user chooses to Cancel and in those cases jquery error will be called for each request.
Here's a link to a gist with the example code:
https://gist.github.com/kavhad/bb0d8e4a446496a6c05a
Note my code is based on usage of jquery for handling all ajax request. If your ajax request are being handled by vanilla javascript, other libraries or frameworks then you can perhaps find some inspiration in this example. The usage of jquery ui is only because of the dialog and stands for a small portion of the code which could easly be swapped out.
Update
Sorry I changed my github account name and that's why link did not work. It should work now.
First of all you say you are trying to make an ajax call to another website, does your call conforms to same origin policy of web browsers? If it does then you are expecting html as a response from your server, changedatatype of the ajax call to dataType: "html", then insert the form into your DOM.
Perhaps the 2 first posts of this serie will help you. They consider ADFS and AJAX requests
What I think I would try to do is to see why the authentication cookies are not transmitted through ajax, and find a mean to send them with my request. Or wrap the ajax call in a function that pre authenticate by retrieving the html form, appending it hidden to the DOM, submitting it (it will hopefully set the good cookies) then send the appropriate request you wanted to send originally
You can do only this type of datatype
"xml": Treat the response as an XML document that can be processed via jQuery.
"html": Treat the response as HTML (plain text); included script tags are evaluated.
"script": Evaluates the response as JavaScript and evaluates it.
"json": Evaluates the response as JSON and sends a JavaScript Object to the success callback.
If you can see in your fiddler that is returning only html then change your data type to html or if that only a script code then you can use script.
You should create a file anyname like json.php and then put the connection to the relayparty website this should works
$.ajax({
url: "json.php",
data: { foobar },
dataType: "json",
type: "POST",
async: false,
cache: false,
success: function (data) {
// do something here
},
error: function (data, status) {
alert(status);
}
});

Categories

Resources