Karl
Karl

Reputation: 595

Retrieving access_token from Twitter Oauth API with jsOAuth

I have a Phonegap application that uses ChildBrowser to Authorize my app to connect with the users Twitter account using Oauth. Once the user signs in their Twitter account an authorize the app to connect, Twitter sends the ChildBrowser to the callback url where I retrieve the request_token from the url. But then I try to call the API to exchange the request_token for the access_token and the application does not continue past that point. It looks like the app breaks during the API call to get the access_token but I cant see how.

Any help would be greatly appreciated!!!

Thank you so much all!

Here is my javascript:

/* -- Twitter START -- */

var Twitter = {
    init:function() {

        var oauth; 
        var requestParams; 
        var options = { 
            consumerKey: 'blahblah',
            consumerSecret: 'blahblah',
            callbackUrl: "http://beaconize.com/" 
        };
        alert(localStorage.twitterKey);
        var cb = ChildBrowser.install(); // install our ChildBrowser ( cb )    
        var twitterKey = "twttrKey"; // what we will store our twitter user information in


        // our storedAccessData and Raw Data
        var storedAccessData, rawData = localStorage.getItem(twitterKey);

        // First thing we need to do is check to see if we already have the user saved!
        if(localStorage.getItem(twitterKey) !== null){

            // If we already have them
            storedAccessData = JSON.parse(rawData); // Parse our JSON object
            options.accessTokenKey = storedAccessData.accessTokenKey; // This is saved when they first sign in
            options.accessTokenSecret = storedAccessData.accessTokenSecret; // this is saved when they first sign in

            oauth = OAuth(options);
            oauth.get('https://api.twitter.com/1/account/verify_credentials.json?skip_status=true',
                function(data) {
                    var entry = JSON.parse(data.text);
                    alert("USERNAME: " + entry.screen_name);
                }
            );
        } else {

            // We don't have a user saved yet
            oauth = OAuth(options);
            oauth.get('https://api.twitter.com/oauth/request_token',
                function(data) {
                    requestParams = data.text;
                    cb.showWebPage('https://api.twitter.com/oauth/authorize?'+data.text); // This opens the Twitter authorization / sign in page     
                    cb.onLocationChange = function(loc){ Twitter.success(loc); }; // When the ChildBrowser URL changes we need to track that
                },
                function(data) { 
                    alert("ERROR: "+data);
                }
            );
        }
    },

    /*
     When The ChildBrowser URL changes we will track it here.
     We will also determine if the request was a success or not here
     */
    success:function(loc) {
        // The supplied oauth_callback_url for this session is being loaded

        /*
         We will check to see if the childBrowser's new URL matches our callBackURL
         */
        if (loc.indexOf("http://beaconize.com/?") >= 0) {

            // Parse the returned URL
            var index, verifier = '';            
            var params = loc.substr(loc.indexOf('?') + 1);

            params = params.split('&');
            for (var i = 0; i < params.length; i++) {
                var y = params[i].split('=');
                if(y[0] === 'oauth_verifier') {
                    verifier = y[1];
                }
            }


            // After the next line, nothing executes. It stops in ChildBrowser on my callback_url.


            oauth.get('https://api.twitter.com/oauth/access_token?oauth_verifier='+verifier+'&'+requestParams,
                      function(data) {               
                        var accessParams = {};
                        var qvars_tmp = data.text.split('&');
                        for (var i = 0; i < qvars_tmp.length; i++) {
                            var y = qvars_tmp[i].split('=');
                            accessParams[y[0]] = decodeURIComponent(y[1]);
                        }

                        oauth.setAccessToken([accessParams.oauth_token, accessParams.oauth_token_secret]);

                        // Save access token/key in localStorage
                        var accessData = {};
                        accessData.accessTokenKey = accessParams.oauth_token;
                        accessData.accessTokenSecret = accessParams.oauth_token_secret;

                        // SETTING OUR LOCAL STORAGE
                        alert("TWITTER: Storing token key/secret in localStorage3");
                        localStorage.setItem(twitterKey, JSON.stringify(accessData));
                      },
                      function(data) { 
                      console.log(data);

                      }
            );
                      oauth.get('https://api.twitter.com/1/account/verify_credentials.json?skip_status=true',
                                function(data) {
                                var entry = JSON.parse(data.text);
                                alert("TWITTER USER: "+entry.screen_name);

                                // FOR EXAMPLE ONLY
                                //app.init();
                                },
                                function(data) {
                                alert("ERROR: " + data); 
                                }
                                );

                      // Since everything went well we can close our childBrowser!                             
                      window.plugins.childBrowser.close();


        } else {
            // do nothing   
        }
    },
    tweet:function() {
        var storedAccessData, rawData = localStorage.getItem(twitterKey);

        storedAccessData = JSON.parse(rawData); // Parse our JSON object
        options.accessTokenKey = storedAccessData.accessTokenKey; // This is saved when they first sign in
        options.accessTokenSecret = storedAccessData.accessTokenSecret; // this is saved when they first sign in

        // jsOAuth takes care of everything for us we just need to provide the options
        oauth = OAuth(options);
        oauth.get('https://api.twitter.com/1/account/verify_credentials.json?skip_status=true',
            function(data) {
                var entry = JSON.parse(data.text);
                Twitter.post();
            }
        );
    },
    /*
     Now that we have the information we can Tweet!
     */
    post:function() {
        var theTweet = $("#tweet").val(); // Change this out for what ever you want!

        oauth.post('https://api.twitter.com/1/statuses/update.json',
            { 'status' : theTweet,  // jsOAuth encodes for us
            'trim_user' : 'true' },
            function(data) {
                var entry = JSON.parse(data.text);
                alert(entry);

                // FOR THE EXAMPLE
                app.done();
            },
            function(data) { 
                alert(data);
            }
        );      
    }
};

/* -- Twitter END -- */

Upvotes: 0

Views: 5048

Answers (2)

Drew Dahlman
Drew Dahlman

Reputation: 4972

Okay so I compared your code with the original project that you are referencing. and here's where I netted out.

Looks like you are missing a couple things that are leading to this breaking.

here is the original code - this should work

oauth.get('https://api.twitter.com/oauth/access_token?oauth_verifier='+verifier+'&'+requestParams,
                      function(data) {               
                        var accessParams = {};
                        var qvars_tmp = data.text.split('&');
                        for (var i = 0; i < qvars_tmp.length; i++) {
                            var y = qvars_tmp[i].split('=');
                            accessParams[y[0]] = decodeURIComponent(y[1]);
                        }

                        oauth.setAccessToken([accessParams.oauth_token, accessParams.oauth_token_secret]);

                        // Save access token/key in localStorage
                        var accessData = {};
                        accessData.accessTokenKey = accessParams.oauth_token;
                        accessData.accessTokenSecret = accessParams.oauth_token_secret;

                        // SETTING OUR LOCAL STORAGE
                        alert("TWITTER: Storing token key/secret in localStorage3");
                        localStorage.setItem(twitterKey, JSON.stringify(accessData));
                      },
                      function(data) { 
                      console.log(data);

                      }
            );
                      oauth.get('https://api.twitter.com/1/account/verify_credentials.json?skip_status=true',
                                function(data) {
                                var entry = JSON.parse(data.text);
                                alert("TWITTER USER: "+entry.screen_name);

                                // FOR EXAMPLE ONLY
                                //app.init();
                                },
                                function(data) {
                                alert("ERROR: " + data); 
                                }
                                );

                      // Since everything went well we can close our childBrowser!                             
                      window.plugins.childBrowser.close();


        } else {
            // do nothing   
        }
    },

One thing to notice and this is where your code differs is the error function for the first oauth request - your code seems to be missing this, which isn't a huge deal - but you have taken out the formatting so those two functions are now one which is causing issues.

if you copy this code and select and paste right over your code and toggle them you will see the minor differences that are causing the issues!

Upvotes: 1

bytespider
bytespider

Reputation: 586

So far looking at your code, everything looks reasonable.

I notice you are doing some of the auth-dance work manually. Have you tried using the fetchRequestToken() & fetchAccessToken() methods? I wrote boiler plate code to demonstrate this.

Can you give the output of the error message? Usually It gives a clue to why Twitter didn't authorise you.

You may find this useful API reference theres also an undocumented method for parsing the url strings parseTokenRequest()

Upvotes: 0

Related Questions