Twitter OAuth with WinJS - twitter-oauth

Trying to authenticate with Twitter since over a week trough my Windows 8 app, but no success.
My app is registered at Twitter and it should be able to read, write and sign in.
I think I've tried all the descriptions at Twitter documentation, but nothing works. Guess the problem is at me, but can't find it.
I get always the 403 forbidden response.
My code:
function getTwitterCredentials() {
WinJS.xhr({
type:"get",
url: "https://api.twitter.com/oauth/authenticate",
headers: {
consumerKey: "ZSNRXXXXXXXXX",
userKey: "GVknHzXXXXXXXXXXXXXXXXXXX",
Authorization: "OAuth",
oauth_consumer_key: "ZSNRtXXXXXXXXXXXXX",
oauth_nonce: "b7efbXXXXXXXXXXXXXXXx",
oauth_signature: "23zb0XXXXXXXXXXXXXXx",
oauth_signature_method: "HMAC-SHA1",
oauth_timestamp: "1368555677",
oauth_token: "1408XXXXXXXXXXXXXXXXXXXXXXXXXXXXx",
oauth_version: "1.0"
}
}).done(function (response) {
//it it works here some will be some action
}, function error(response) {
console.log(response.status);
});
}
Someone has experience whit this issue?
Thanks Marlowe

Here's some demo JS code I slightly modified from an existing sample on our site from the oAuth Web Authentication Broker for Win8 demo. Search 'oob' for my changes, they are minor.
In addition, the Linq to Twitter project is pretty awesome so may want to consider checking that out as well and would prob be a bit easier. It handles the auth fairly automatically and doesn't require having to enter in the token response.
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
(function () {
"use strict";
var page = WinJS.UI.Pages.define("/html/oAuthTwitter.html", {
ready: function (element, options) {
document.getElementById("oAuthTwitterLaunch").addEventListener("click", launchTwitterWebAuth, false);
//did read that this is required for oAuth in a win8 app, however twitter uses 'oob' for a desktop app's callback url.
//in fact your app will show it.
//var endURI = Windows.Security.Authentication.Web.WebAuthenticationBroker.getCurrentApplicationCallbackUri();
//document.getElementById("TwitterCallbackURL").innerText = endURI.displayUri;
}
});
function sendRequest(url) {
try {
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.send(null);
return request.responseText;
} catch (err) {
WinJS.log("Error sending request: " + err, "Web Authentication SDK Sample", "error");
}
}
function sendPostRequest(url, authzheader) {
try {
var request = new XMLHttpRequest();
request.open("POST", url, false);
request.setRequestHeader("Authorization", authzheader);
request.send(null);
if (request.status != "200") {
console.log(request);
}
return request.responseText;
} catch (err) {
WinJS.log("Error sending request: " + err, "Web Authentication SDK Sample", "error");
}
}
function isValidUriString(uriString) {
var uri = null;
try {
uri = new Windows.Foundation.Uri(uriString);
}
catch (err) {
}
return uri !== null;
}
var authzInProgress = false;
function launchTwitterWebAuth() {
var twitterURL = "https://api.twitter.com/oauth/request_token";
// Get all the parameters from the user
var clientID = document.getElementById("TwitterClientID").value;
if (clientID === null || clientID === "") {
WinJS.log("Please enter a ClientID for Twitter App", "Web Authentication SDK Sample", "error");
return;
}
var clientSecret = document.getElementById("TwitterSecret").value;
if (clientSecret === null || clientSecret === "") {
WinJS.log("Please enter a Secret for Twitter App", "Web Authentication SDK Sample", "error");
return;
}
var callbackURL = document.getElementById("TwitterCallbackURL").value;
//if (!isValidUriString(callbackURL)) {
// WinJS.log("Please enter a Callback URL for Twitter", "Web Authentication SDK Sample", "error");
// return;
//}
if (authzInProgress) {
document.getElementById("TwitterDebugArea").value += "\r\nAuthorization already in Progress ...";
return;
}
// Acquiring a request token
var timestamp = Math.round(new Date().getTime() / 1000.0);
var nonce = Math.random();
nonce = Math.floor(nonce * 1000000000);
// Compute base signature string and sign it.
// This is a common operation that is required for all requests even after the token is obtained.
// Parameters need to be sorted in alphabetical order
// Keys and values should be URL Encoded.
var sigBaseStringParams = "oauth_callback=" + encodeURIComponent(callbackURL);
sigBaseStringParams += "&" + "oauth_consumer_key=" + clientID;
sigBaseStringParams += "&" + "oauth_nonce=" + nonce;
sigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
sigBaseStringParams += "&" + "oauth_timestamp=" + timestamp;
sigBaseStringParams += "&" + "oauth_version=1.0";
var sigBaseString = "POST&";
sigBaseString += encodeURIComponent(twitterURL) + "&" + encodeURIComponent(sigBaseStringParams);
var keyText = clientSecret + "&";
var keyMaterial = Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(keyText, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);
var macAlgorithmProvider = Windows.Security.Cryptography.Core.MacAlgorithmProvider.openAlgorithm("HMAC_SHA1");
var key = macAlgorithmProvider.createKey(keyMaterial);
var tbs = Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(sigBaseString, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);
var signatureBuffer = Windows.Security.Cryptography.Core.CryptographicEngine.sign(key, tbs);
var signature = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(signatureBuffer);
var dataToPost = "OAuth oauth_callback=\"" + encodeURIComponent(callbackURL) + "\", oauth_consumer_key=\"" + clientID + "\", oauth_nonce=\"" + nonce + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + timestamp + "\", oauth_version=\"1.0\", oauth_signature=\"" + encodeURIComponent(signature) + "\"";
var response = sendPostRequest(twitterURL, dataToPost);
var oauth_token;
var oauth_token_secret;
var keyValPairs = response.split("&");
for (var i = 0; i < keyValPairs.length; i++) {
var splits = keyValPairs[i].split("=");
switch (splits[0]) {
case "oauth_token":
oauth_token = splits[1];
break;
case "oauth_token_secret":
oauth_token_secret = splits[1];
break;
}
}
document.getElementById("TwitterDebugArea").value += "\r\nOAuth Token = " + oauth_token;
document.getElementById("TwitterDebugArea").value += "\r\nOAuth Token Secret = " + oauth_token_secret;
// Send the user to authorization
twitterURL = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth_token;
document.getElementById("TwitterDebugArea").value += "\r\nNavigating to: " + twitterURL + "\r\n";
var startURI = new Windows.Foundation.Uri(twitterURL);
//var endURI = new Windows.Foundation.Uri(callbackURL);
//we use 'oob' in the request_auth, but now for authorize, we use the apps URI.
var endURI = Windows.Security.Authentication.Web.WebAuthenticationBroker.getCurrentApplicationCallbackUri();
authzInProgress = true;
Windows.Security.Authentication.Web.WebAuthenticationBroker.authenticateAsync(
Windows.Security.Authentication.Web.WebAuthenticationOptions.none, startURI, endURI)
.done(function (result) {
document.getElementById("TwitterReturnedToken").value = result.responseData;
document.getElementById("TwitterDebugArea").value += "Status returned by WebAuth broker: " + result.responseStatus + "\r\n";
if (result.responseStatus === Windows.Security.Authentication.Web.WebAuthenticationStatus.errorHttp) {
document.getElementById("TwitterDebugArea").value += "Error returned: " + result.responseErrorDetail + "\r\n";
}
authzInProgress = false;
}, function (err) {
WinJS.log("Error returned by WebAuth broker: " + err, "Web Authentication SDK Sample", "error");
document.getElementById("TwitterDebugArea").value += " Error Message: " + err.message + "\r\n";
authzInProgress = false;
});
}
})();

Related

Cannot get FileLeafRef property in SharePoint Rest API

Hi we are trying to retrieve the link URL of page in Site Pages using REST API the problem is that we cannot find the Name FileLeafRef property value.FileLeafReaf = null.
function fn_getListItems(webUrl,listTitle, queryText)
{
var viewXml = '<View><Query>' + queryText + '</Query></View>';
var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/getitems";
var queryPayload = {
'query' : {
'__metadata': { 'type': 'SP.CamlQuery' },
'ViewXml' : viewXml
}
};
return fn_executeJson(url,"POST",null,queryPayload);
}
function fn_getListViewItems(webUrl,listTitle,viewTitle)
{
var url = webUrl + "/_api/web/lists/getByTitle('" + listTitle + "')/Views/getbytitle('" + viewTitle + "')/ViewQuery";
return fn_executeJson(url).then(
function(data){
var viewQuery = data.d.ViewQuery;
return fn_getListItems(webUrl,listTitle,viewQuery);
});
}
function fn_executeJson(url,method,headers,payload)
{
method = method || 'GET';
headers = headers || {};
headers["Accept"] = "application/json;odata=verbose";
if(method == "POST") {
headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
}
var ajaxOptions =
{
url: url,
type: method,
contentType: "application/json;odata=verbose",
headers: headers
};
if (typeof payload != 'undefined') {
ajaxOptions.data = JSON.stringify(payload);
}
return $.ajax(ajaxOptions);
}
Thanks.
SharePoint stores the full URL of a file in a hidden column EncodedAbsUrl.
So, you can request it explicitly as:
/_api/web/lists/getbytitle('Site Pages')/items?$select=*,EncodedAbsUrl
After that, you can directly use it somewhat as below, watch out for the quotes :
var items = data.d.results;
$.each(items, function(index, value) {
//Append results to DIV
$("#lstGlobalNews").append("<tr><td class='ms-vb2'><a href="+value.EncodedAbsUrl+" target='_blank'>"+value.Title+"</a></td><td class='ms-vb2' style='text-align: right;'>"+fn_FormatDate(value.Date_x0020_Posted)+"</td></tr>");
});
To retrieve FileLeafRef property, it needs to be explicitly specified in $select query option, for example:
/_api/web/lists/getbytitle('Site Pages')/items?$select=FileLeafRef
As alternative option it could also be retrieved via File resource, for example:
/_api/web/lists/getbytitle('Site Pages')/items?$select=File/Name&$expand=File
The FileLeafRef property only get the file name. If you want to get the file url, we need use ServerRelativeUrl property of file.
The REST API using this.
/_api/web/lists/getbytitle('Site%20Pages')/items?$select=File/ServerRelativeUrl&$expand=File

Issue with the submitAdapterAuthentication() method of the ChallengeHandler in MobileFirst v.6.3

We have an issue with the submitAdapterAuthentication() method of the ChallengeHandler in IBM MobileFirst v.6.3.
We assign callback functions to the properties 'onSuccess' and 'onFailure' in the options object.
We then provide the options object to submitAdapterAuthentication(invocationData, options) and execute it.
var ch = WL.Client.createChallengeHandler(securityTest);
//////////////////
function login (user, pass) {
tempUser = {username: user, password: pass};
userObj.user = user;
var auth = "Basic " + window.btoa(user + ":" + pass);
var invocationData = {
parameters: [auth, user],
adapter: "SingleStepAuthAdapter",
procedure: "submitLogin"
};
var options = {
onSuccess: iWon,
onFailure: iLost,
invocationContext: {invocationData: invocationData},
timeout: 10000
};
ch.submitAdapterAuthentication(invocationData, options);
});
function iWon(response) {
WL.Logger.debug('Login success! Response: ' + JSON.stringify(response));
//update user info, as somehow isUserAuthenticated return false without it
WL.Client.updateUserInfo(function(response) {
WL.Logger.debug('Updated User Info success! Response: ' + JSON.stringify(response));
});
}
function iLost(response) {
WL.Logger.debug('ERROR. Login failed! Response: ' + JSON.stringify(response));
}
Neither the onSuccess (iWon) or the onFailure (iLost) is called after executing submitAdapterAuthentication(invocationData, options).
How do we know if the authentication was successful?
Which options, events, callbacks or promises shall we look for and use?
We have also posted the issue here:
submitAdapterAuthentication not working
You are missing the definition of the functions
ch.isCustomResponse = function(response){...}
ch.handleChallenge = function(response){...}
Your code should look more like this
var ch = WL.Client.createChallengeHandler(securityTest);
ch.isCustomResponse = function(response) {
if (!response||!response.responseJSON||response.responseText === null) {
return false;
}
if (typeof(response.responseJSON.authRequired) !== 'undefined'){
return true;
} else {
return false;
}
};
ch.handleChallenge = function(response){
var authRequired = response.responseJSON.authRequired;
if (authRequired == true){
// handle the case when authentication is needed, i.e., show login form etc.
if (response.responseJSON.errorMessage) {
// authentication failed, show a message to the user indicating what went wrong
// call the login failed function or move it's contents here
iLost(response);
}
} else if (authRequired == false){
// no authentication is needed
ch.submitSuccess();
// call the login success function or move it's contents here
iWon(response);
}
};
//////////////////
function login (user, pass) {
tempUser = {username: user, password: pass};
userObj.user = user;
// is the first parameter expected by submitLogin the username or the
// Basic Authentication encoded string ???
var auth = "Basic " + window.btoa(user + ":" + pass);
var invocationData = {
parameters: [auth, user],
adapter: "SingleStepAuthAdapter",
procedure: "submitLogin"
};
ch.submitAdapterAuthentication(invocationData, {});
});
function iWon(response) {
WL.Logger.debug('Login success! Response: ' + JSON.stringify(response));
//update user info, as somehow isUserAuthenticated return false without it
WL.Client.updateUserInfo(function(response) {
WL.Logger.debug('Updated User Info success! Response: ' + JSON.stringify(response));
});
}
function iLost(response) {
WL.Logger.debug('ERROR. Login failed! Response: ' + JSON.stringify(response));
}
For more information on adapter-based authentication visit http://www-01.ibm.com/support/knowledgecenter/SSHS8R_6.3.0/com.ibm.worklight.dev.doc/devref/t_adapter_based_authenticator.html?lang=en
You should also check the getting started module on adapter-based authentication for hybrid applications https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-6-3/authentication-security/adapter-based-authentication/adapter-based-authentication-hybrid-applications/

Log in with facebook in app using jquery mobile

I am Making an Android App with the help of(jquery mobile) in which in need your help if i want to login with facebook in my app how i can do these thing please help me out
in have AppID and AppSecret
please explain me in step to step process
1) Add ChildBrowser Phongap Plugin for android in your app.
2) Your login page add this code
$("#btn_log_facebook").on("click", function(event){
if(event.handled !== true) {
var fb = FBConnect.install();
var client_id = your_client_id;
var redir_url = your_redir_url;
fb.connect(client_id,redir_url,"touch");
event.handled = true;
}
return false;
});
3) Create fb_connect.js file
function FBConnect()
{
if(window.plugins.childBrowser == null)
{
ChildBrowser.install();
}
}
FBConnect.prototype.connect = function(client_id,redirect_uri,display)
{
this.client_id = client_id;
this.redirect_uri = redirect_uri;
var authorize_url = "https://graph.facebook.com/oauth/authorize?";
authorize_url += "client_id=" + client_id;
authorize_url += "&redirect_uri=" + redirect_uri;
authorize_url += "&display="+ ( display ? display : "touch" );
authorize_url += "&type=user_agent";
var ref = window.open(authorize_url, 'random_string', 'location=no');
ref.addEventListener('loadstart', function(event) {
//console.log(event.type + ' - ' + event.url);
} );
ref.addEventListener('loadstop', function(event) {
var access_token = event.url.split("access_token=")[1];
var error_reason = event.url.split("error_reason=")[1];
if(access_token != undefined){
access_token = access_token.split("&")[0];
loginWithFacebookUserInfo(access_token);
setTimeout(function() {
ref.close();
}, 5000);
}
if(error_reason != undefined){
window.location.href = "register.html";
setTimeout(function() {
ref.close();
}, 5000);
}
//console.log(event.url); alert(event.type + ' - ' + event.url);
} );
ref.addEventListener('exit', function(event) {
//console.log(event.type);
} );
}

How to send facebook api batch request with node.js

How do I send facebook api batch request with node.js?
FB's examples do not work.
but I finally got danwong/restler.js to work like this:
exports.updateUserFriends = function (userData, next) {
var TOKEN = userData[1];
var fbID = userData[3].id;
var batchreq = {};
batchreq.batch = [];
batchreq.batch.push({"method":"GET", "relative_url":fbID+"/"});
batchreq.batch.push({"method": "GET", "relative_url":fbID+"/friends?limit=50"});
restler.post('https://graph.facebook.com?access_token='+TOKEN,
{data:"batch="+JSON.stringify(batchreq.batch)})
.on('complete', function(data) {
console.log(data);
return next;
});
};
So I thought I'd post this to save someone else a bit of frustration.
First thing to note is that, "Only POST is allowed for batch requests" in FB Api.
var https = require('https');
var url = '/?access_token='+ YOUR_ACCESS_TOKEN_HERE,
batch=[{
"method":"GET",
"relative_url":page + "/insights"
}, {
"method": "GET",
"relative_url":page
}];
url = url + '&batch=' + JSON.stringify(batch);
console.log(url);
var options = {
host:'graph.facebook.com',
path:url,
method: 'POST'
};
var req =https.request(options, function(res){
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
var body='';
res.on('data', function(chunk){
// console.log("body:" + chunk);
body += chunk;
});
res.on('end', function(){
var fbRes = JSON.parse(body);
console.log(fbRes);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();

JQuery ajax form submit works when debugging but not without

I've got a form that is loaded on to a page using ajax. The form is then submitted using the malsup jquery form plugin.
Strangely the form works when I add a firebug breakpoint line or an alert into this method, but when I remove the alert or debug, the submit code never runs.
function addAttachment(attachmentType, path){
var typeSplit = attachmentType.split(":");
if(path == null){
path = "";
}
var url = "/add/" + typeSplit[0] + "/" + typeSplit[1];
addOverlayDivs(); //adds div to load the form into
// load the form
var snippet = $('#overlay').load(url, function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an error: ";
$("#overlay").html(msg + xhr.status + " " + xhr.statusText);
}
});
var prefix = typeSplit[0];
var type = typeSplit[1];
//this alert will cause the submit form to work
alert("bind overlay called");//if I comment this out the formsubmit doesn't work
var options = {
target: null, // target element(s) to be updated with server response
beforeSubmit: showRequest,
success: showResponse,
url: "/add/" + prefix + "/" + type,
type: "POST",
dataType: "json"
};
$('#overlayForm').submit(function() {
$(this).ajaxSubmit(options);
// always return false to prevent standard browser submit and page navigation
return false;
});}
I've tried with and without using $(document).ready and that doesn't make a difference.
Any ideas?
May be you need to call later part of your function after load completed,Try this
$(document).ready(function(){
function addAttachment(attachmentType, path){
var typeSplit = attachmentType.split(":");
if(path == null){
path = "";
}
var url = "/add/" + typeSplit[0] + "/" + typeSplit[1];
addOverlayDivs(); //adds div to load the form into
// load the form
var snippet = $('#overlay').load(url, function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an error: ";
$("#overlay").html(msg + xhr.status + " " + xhr.statusText);
}
Dowork();//function call after load complete
});
}
function Dowork(){
var prefix = typeSplit[0];
var type = typeSplit[1];
//this alert will cause the submit form to work
var options = {
target: null, // target element(s) to be updated with server response
beforeSubmit: showRequest,
success: showResponse,
url: "/add/" + prefix + "/" + type,
type: "POST",
dataType: "json"
};
$('#overlayForm').submit(function() {
$(this).ajaxSubmit(options);
// always return false to prevent standard browser submit and page navigation
return false;
});
}
});