Twitter Authentication In MetroApps(HTML5/WINJs)


#1

Hello,
I’m trying to integrate Twitter into Metro Application(Html/js). I want the user to be authenticated, for which a 3 pipe line access mechanism to be followed.
While, requesting for access token 401 error is being returned, stating failed to validate signature and OAuthToken.
My Consumer Key: fbL8qhMgeR0qKLX3zvOwNQ and Consumer Secret :XXXXXXX

Below are the code snippets being used

  function launchTwitterWebAuth() {

        //  var twitterURL = "https://api.twitter.com/oauth/authenticate?force_login=true";
        var twitterURL = "https://api.twitter.com/oauth/request_token";
        var ClientID = "fbL8qhMgeR0qKLX3zvOwNQ";
        var ClientSecret = "XXXXXX";
        var callbackURL = "oob";

        // Acquiring a request token
        var timestamp = Math.round(new Date().getTime() / 1000.0);
        var nonce = Windows.Security.Cryptography.CryptographicBuffer.generateRandomNumber();// 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 = encodeURIComponent(Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(signatureBuffer));
        var dataToPost = "OAuth oauth_callback=\"" + encodeURIComponent(callbackURL) + "\", oauth_consumer_key=\"" + ClientID + "\", oauth_nonce=\"" + nonce + "\",oauth_signature=\"" + encodeURIComponent(signature) + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + timestamp + "\", oauth_version=\"1.0\"";
        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;
            }



        }
    }

    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");
        }
    }

Signature generated from my side is:
OAuth oauth_callback=“oob”, oauth_consumer_key=“fbL8qhMgeR0qKLX3zvOwNQ”, oauth_nonce=“2382863001”,oauth_signature=“FUwgewc2ZkdkB4ESJ8Mq8EE4EN4%253D”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“1381147694”, oauth_version=“1.0”

From Oauth Tool is:
Authorization: OAuth oauth_consumer_key=“fbL8qhMgeR0qKLX3zvOwNQ”, oauth_nonce=“b5e8972ec9ad4fef1f4b1dfab6d7d795”, oauth_signature=“L%2FdrF2tgQ%2BDfh5JYNTG9qmQoEHc%3D”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“1381147648”, oauth_token=“70405803-OqyNCvkwhXQZnKuwKxydNv44XKDO37Kke2qCmRSnf”, oauth_version=“1.0”

Could you guys please help, where am i going wrong


#2

Please be more careful about posting your consumer secret in public forums.

The OAuth Tool on this site can’t really help you with this step of OAuth very well. (It’s a tool for making requests to the API itself, not to the auth negotiation methods.)

Take a look at [node:204] for some debugging tips to try. I would also make sure that the URI/URL encoding methods you’re using are the correct ones – some languages’ default implementations aren’t to spec.


#3

Hi,
I figured out where it went wrong. An Additional encoding has led to error.
Now I’m able to receive oauth_token and oauth_secret.
Now my next target is to authenticate the user.
As it is a metroapp, could any one let me know what should be the callbackURL or endURL that should be passed as it is a metroapp.
Below is the code snippet.

var TwitterAuthURL = “https://api.twitter.com/oauth/authenticate?oauth_token=” + oauth_token + “&force_login=true”;
var callBackURL = Windows.Security.Authentication.Web.WebAuthenticationBroker.getCurrentApplicationCallbackUri().absoluteUri;
var startURI = new Windows.Foundation.Uri(TwitterAuthURL);
var endURI = new Windows.Foundation.Uri(callBackURL);

        Windows.Security.Authentication.Web.WebAuthenticationBroker.authenticateAsync(Windows.Security.Authentication.Web.WebAuthenticationOptions.none, startURI,endURI).done(
            function (result) {
                if (result.responseStatus == Windows.Security.Authentication.Web.WebAuthenticationStatus.success) {
                }
                else {

                }
            },
            function (error) {
            }
            );
I could sign-in and it shows me some token to be used, but the Web Authentication Broker is not getting closed. could any one please help me on this.