简体   繁体   中英

Ajax REST API Twitter Authorization issue: error 400 Bad Request

I can't get to work an Ajax call thru JQuery to twitter API. My problem is the authorization. This is what I'm doing and it seem all right to me:

function loadTwitter(sLat, sLon, sRad, dFrom, dTo){
            arrayTweets = new Array();
            var sRadKm = sRad/1000;
            dFrom = dFrom/1000;
            dTo = dTo/1000;
                    var twitterUrlPath = "https://api.twitter.com/1.1/search/tweets.json";
            var auth = "OAuth oauth_consumer_key='0kfWFbA6xxxrKjpg2oQ', oauth_nonce='87abf089674bxxx8bd50823c500c', oauth_signature='URF2O%2BdSS0ExxxP8pqQWnA%3D', oauth_signature_method='HMAC-SHA1', oauth_timestamp='1390287341', oauth_token='2287933520-fuUBrz3AZ0GoopxxxxsfE4nLZZ5QJryB8cFZuR0', oauth_version='1.1'";
            var urlTwitter = "?geocode=" + sLat + "," + sLon + "," + sRadKm + "km&count=100"; 
            $.ajax({
                    type: "GET",
                    async: false,
                    accept: "application/json",
                    url: twitterUrlPath + urlTwitter,
                    dataType: "jsonp",
                    beforeSend : function(req) {
                        req.setRequestHeader('Authorization', auth);
                    }, 
                    success: function (resp, status, xhr) {
                       $("#message").html("STATUS: " + xhr.status + " " + xhr.statusText + "\n" + resp);
                       $("#message").hide();
                       $.each(resp, function() {
                            $.each(this, function(i, item) {
                                arrayTweets.push(item);
                            });

                        });

                        displayTweets();
                    },
                    error: function(resp, status, xhr){
                        $("#message").html("ERROR: " + xhr.status + " " + xhr.statusText + "\n" + resp.e);
                        $("#message").show();
                    }
                });
        }

I keep getting 400 Bad Request.

Also, if I want to call it thru poster (firefox sniffer), how do I pass the auth parameters? Thanks,

So... we were sitting with the same issues when trying to solve this, while it still puzzles me that Twitter does not support client side authorized requests for data here is the answer the way we managed it:

Since we are dealing with a jsonp call you cannot actually include headers in the call ref. How can I access auth-only Twitter API methods from a web application

So setRequestHeader is a no go.

What you need to do instead is to build the entire request in the url for the jquery ajax request however also here there are a few caveats to be aware of:

When you create the base url for the signature it needs to be the EXACT url that you will be sending to Twitter for example you need the callback defined in the signature process (which you are hopefully doing serverside) so something like this:

    parameters = {
        callback:"callback",
        q:"1",
        oauth_consumer_key : [your consumer key],
        oauth_token : [token from initial oauth call],
        oauth_nonce : [random alphanumeric 32 bytes base64],
        oauth_timestamp : Math.round(today.getTime()/1000),
        oauth_signature_method : 'HMAC-SHA1',
        oauth_version : '1.0'
    }; 

to create the signature serverside I would recommmend using this lib: https://github.com/mikeal/oauth-sign/blob/master/index.js

Then on the client side to do the request via jquery ajax a couple things as well:

    $.ajax({
        type: "GET",
        accept: "*/*",
        contentType: "application/x-www-form-urlencoded",
        dataType: "jsonp",
        jsonpCallback: "callback",
        cache: true,
        url: "https://api.twitter.com/1.1/search/tweets.json?" + "q=1" + this.authString,
        success: function (data, bla, test) {
            console.log(data, bla, test);
        },
        error: function (data) {
            console.log(data)
        }
    });

If you notice the cache set to true this means that jquery does not append a timestamp on the url call important sonce the url should reflect the signature base url also notice we have defined the jsonpCallback again to reflect the exact base url.

Be sure to encode the values for the url call on the client side here we reused the function from the lib:

SearchQuery.prototype.encodeRFC3986 = function (str) {
    return encodeURIComponent(str)
        .replace(/!/g, '%21')
        .replace(/\*/g, '%2A')
        .replace(/\(/g, '%28')
        .replace(/\)/g, '%29')
        .replace(/'/g, '%27')
        ;
}

eg.

authString += "&" + this.encodeRFC3986("oauth_signature") + "=" + this.encodeRFC3986(this.searchObj.signature);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM