Using Twitter REST API 1.1 throws 401 unauthorized error, but using Twitter REST API 1.0 works fine. Why?


#1

I’m trying to call this REST API:
https://api.twitter.com/1.1/statuses/user_timeline.json

I set up to use OAuth 1.0 with the following parameters already set up in the Twitter application on dev.twitter.com:
OAuth consumer key
OAuth signature method
OAuth token
OAuth version (1.0)
consumer secret
OAuth token secret

However every time I build my OAuth 1.0 header and call the REST API above, I get a 401 unauthorized error returned.

Yet, when I call the 1.0 REST API, it works. Why?


#2

API v1 is more permissive with common OAuth and HTTP encoding errors. API v1.1 is more strict. It’s also possible that in API v1 your request wasn’t considered as authenticated, since that method had fall-back support to an unauthenticated context when possible. API v1.1 has no such affordances. See [node:204] for some debugging tips.


#3

As of this morning my application has started returning 401 unauthorized error getting user timelines and status timelines for both search and just normal queries.

I am using both my oauth consumer key from my application to exchange for an oauthToken,

which I then use to get or search tweets. It was working all yesterday using V1.1 and for the past week, and it temporary worked today, and now I am getting constant 401 unauthorized access errors when getting tweets from both search and status time lines.

Is there something wrong with my account, is something wrong with the twitter api that I am not aware of???

Please help. This is getting embarassing…


#4

https://api.twitter.com/1.1/statuses/user_timeline.json?
https://api.twitter.com/1.1/search/tweets.json?

These are the end points I am using. As I said everything was working for the last week and now I am getting 401 error code unauthorized.

Could you tell me about this inconsistency. I followed the development guidelines well, and frustrated.

Makes you wonder what the status of the API is yet it states everything is working fine. Is it my account that is being penalized, and for what reason…

This is a client’s website we are talking about here. I need help???

I have never felt embarassed of a social networking site who tell me to implement one way which works for a couple of days, and then fails after…


#5

I am posting my code here: .NET:

GetProfileTwitterFeeds(), I am sure you can apprciate the deligence - which was working for the last week but stopped today. I fear my account is being tampered with, and I want to know why Twitter is using MALICE against me Taylor Singletary???/

    public enum OauthHeaderType { Basic = 0, Bearer = 1 }

    private string GetOauthHeader(OauthAuthentication oauthentication, OauthHeaderType oauthHeaderType)
    {

        var oauth_version = "1.0";
        var oauth_signature_method = "HMAC-SHA1";
        var oauth_nonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));

        var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,
                                               DateTimeKind.Utc);
        var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();

        var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
            "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}";

        var baseString = string.Format(baseFormat,
                                    oauthentication.ConsumerKey,
                                    oauth_nonce,
                                    oauth_signature_method,
                                    oauth_timestamp,
                                    oauthentication.TokenKey,
                                    oauth_version
                                    );


        var compositeKey = string.Concat(Uri.EscapeDataString(oauthentication.ConsumerSecret),
                    "&", Uri.EscapeDataString(oauthentication.TokenSecret));

        string oauth_signature;

        using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
        {
            oauth_signature = Convert.ToBase64String(
                hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
        }

        var headerFormat = oauthentication.ConsumerKey + ":" + oauthentication.ConsumerSecret;
        headerFormat = Convert.ToBase64String(ASCIIEncoding.UTF8.GetBytes(headerFormat));

        return oauthHeaderType.ToString() + " " + headerFormat;
    }


    private string GetOauthHeader(OauthHeaderType oauthHeaderType, string bearerToken)
    {
        return oauthHeaderType.ToString() + " " + bearerToken;
    }

    public string GetOauthToken(OauthAuthentication oauthAuthentication)
    {
        StreamReader reader = null;
        HttpWebRequest request = null;

        var oauthHeader = GetOauthHeader(oauthAuthentication, OauthHeaderType.Basic);
        try
        {
            request = WebRequest.Create("https://api.twitter.com/oauth2/token") as HttpWebRequest;

            request.Headers.Add("Authorization", oauthHeader);
            request.Method = "POST";

            if (request != null)
            {
                request.ContentType = "application/x-www-form-urlencoded";
                var bytes = UTF8Encoding.ASCII.GetBytes("grant_type=client_credentials");
                request.ContentLength = bytes.Length;
                request.GetRequestStream().Write(bytes, 0, bytes.Length);

                using (var response = request.GetResponse() as HttpWebResponse)
                {
                    using (Stream respStream = response.GetResponseStream())
                    {
                        if (respStream != null)
                        {
                            reader = new StreamReader(respStream);

                            string xmlString = reader.ReadToEnd();
                            reader.Close();
                            return xmlString.Split(new char[] { ',' })[1].Split(new char[] { ':' })[1].Split(new char[] { '}', '"' }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                        }
                    }
                }
            }
            return null;
        }
        catch (Exception e)
        {
            if (reader != null)
                reader.Close();
            throw e;
        }
    }

#6

Actually this is annoying, I have found the solution to my problem.

Overnight Twitter decided when you want to exchange your token for a barer token it returns a json string with the token as the first parameter yet innitially before today the token was the second parameter, So my function should now change the index on spliting of the returned string to take the 0 index value and not the 2nd.

Very annoying. So I had to change my function below on returned value: note the index [0] from [1]

Hope it helps somebody using position parameters.

public string GetOauthToken(OauthAuthentication oauthAuthentication) { StreamReader reader = null; HttpWebRequest request = null;
        var oauthHeader = GetOauthHeader(oauthAuthentication, OauthHeaderType.Basic);
        try
        {
            request = WebRequest.Create("https://api.twitter.com/oauth2/token") as HttpWebRequest;

            request.Headers.Add("Authorization", oauthHeader);
            request.Method = "POST";

            if (request != null)
            {
                request.ContentType = "application/x-www-form-urlencoded";
                var bytes = UTF8Encoding.ASCII.GetBytes("grant_type=client_credentials");
                request.ContentLength = bytes.Length;
                request.GetRequestStream().Write(bytes, 0, bytes.Length);

                using (var response = request.GetResponse() as HttpWebResponse)
                {
                    using (Stream respStream = response.GetResponseStream())
                    {
                        if (respStream != null)
                        {
                            reader = new StreamReader(respStream);

                            string xmlString = reader.ReadToEnd();
                            reader.Close();
                            return xmlString.Split(new char[] { ',' })[0].Split(new char[] { ':' })[1].Split(new char[] { '}', '"' }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                        }
                    }
                }
            }
            return null;
        }
        catch (Exception e)
        {
            if (reader != null)
                reader.Close();
            throw e;
        }
    }

#7

Hi Martin,

If it’s possible, I’d highly recommend that you send the response through a JSON parser/deserializer and then read from the resulting dictionary. There’s no guarantee that the order of fields in a response will remain unchanged, and we may also add new fields over time. I’d hate for this same problem to keep causing you problems.

-Sean


#8

Hey I’m doing an assignment for a class and we have to use the Twitter Rest API. I don’t why I keep getting the 401 error and when my professor runs it it works. Can anyone help? I’m tearing my hair out over here.

import sys import time from urllib2 import URLError from httplib import BadStatusLine from functools import partial from sys import maxint import json import twitter

def oauth_login():

CONSUMER_KEY='***'
CONSUMER_SECRET='***'
OAUTH_TOKEN='***'
OAUTH_TOKEN_SECRET='***'

auth = twitter.oauth.OAuth(OAUTH_TOKEN, OAUTH_TOKEN_SECRET,
                           CONSUMER_KEY, CONSUMER_SECRET)

twitter_api = twitter.Twitter(auth=auth)
return twitter_api

def make_twitter_request(twitter_api_func, max_errors=10, *args, **kw):

    def handle_twitter_http_error(e, wait_period=2, sleep_when_rate_limited=True):

            if wait_period > 3600:
                print >> sys.stderr, 'Too many retries. Quitting.'
                raise e

            if e.e.code ==401:
                print >> sys.stderr, 'Encountered 401 Error (Not Authorized)'
                return None
            elif e.e.code ==404:
                print >> sys.stderr, 'Encountered 404 Error (Not Found)'
                return None
            elif e.e.code ==429:
                print >> sys.stderr, 'Encountered 429 Error (Rate Limit Exceeded)'
                if sleep_when_rate_limited:
                    print >> sys.stderr, "Retrying in 15 minutes...ZZZ..."
                    sys.stderr.flush()
                    time.sleep(60*15 + 5)
                    print sys.stderr, '...ZZZ...Awake now and trying again.'
                    return 2
                else:
                    raise e
            elif e.e.code in (500, 502, 503, 504):
                print >> sys.stderr, 'Encountered %i Error . Retrying in %i seconds' %\
                      (e.e.code, wait_period)
                time.sleep(wait_period)
                wait_period *= 1.5
                return wait_period
            else:
                raise e

    wait_period = 2
    error_count = 0

    while True:
            try:
                return twitter_api_func(*args, **kw)
            except twitter.api.TwitterHTTPError, e:
                error_count = 0
                wait_period = handle_twitter_http_error(e, wait_period)
                if wait_period is None:
                    return
            except URLError, e:
                error_count += 1
                print >> sys.stderr, "URLError encountered. Continuing."
            if error_count > max_errors:
                print >> sys.stderr, "Too many consecutive errors...bailing out."
                raise

def get_user_profile(twitter_api, screen_names=None, user_ids=None):
assert (screen_names !=None) != (user_ids !=None),
“Must have screen_names or user_ids, but not both”

            items_to_info = {}

            items = screen_names or user_ids

            while len(items) > 0:
                items_str = ',' .join([str(item) for item in items[:100]])
                items = items[100:]

            if screen_names:
                response = make_twitter_request(twitter_api.users.lookup, screen_name=items_str)

            else:
                response = make_twitter_request(twitter_api.users.lookup, user_id=items_str)

            for user_info in response:
                if screen_names:
                    items_to_info[user_info['screen_name']] = user_info
                else:
                    items_to_info[user_info['id']] = user_info

                return items_to_info

def get_friends_followers_ids(twitter_api, screen_name=None, user_id=None,
friends_limit=maxint, followers_limit=maxint):

assert(screen_name != None) != (user_id != None), \
"Must have screen_name or user_id but not both"

get_friends_ids = partial(make_twitter_request, twitter_api.friends.ids,
                          count=5000)
get_followers_ids = partial(make_twitter_request, twitter_api.followers.ids,
                            count=5000)
friends_ids, followers_ids = [], []

for twitter_api_func, limit, ids, label in [
                [get_friends_ids, friends_limit, friends_ids, "friends"],
                [get_followers_ids, followers_limit, followers_ids, "followers"]
            ]:
    if limit == 0: continue

    cursor = -1

    while cursor != 0:

        if screen_name:
            response = twitter_api_func(screen_name=screen_name, cursor=cursor)

        else:
            response = twitter_api_func(user_id=user_id, cursor=cursor)

        if response is not None:
            ids += response['ids']
            curosr = response['next_cursor']

        print >> sys.stderr, 'Fetched {0} total {1} ids for {2}'.format(len(ids),
                                                label, (user_id or screen_name))

        if len(ids) >= limit or response is None:
            break
    return friends_ids[:friends_limit], followers_ids[:followers_limit]


            
    
    
    #9.16 9.17 9.19 9.22

twitter_api=oauth_login()
response = make_twitter_request(twitter_api.users.lookup, screen_name=“max_herbowy”)
print json.dumps(response, indent=1)
print twitter_api
print get_user_profile(twitter_api, screen_names=[“max_herbowy”])
friends_ids, followers_ids = get_friends_followers_ids(twitter_api,
screen_name=“max_herbowy”,
friends_limit=10,
followers_limit=10)
print friends_ids
print followers_ids


#9

( user_id = user_id , kurzor = kurzor–followers_ids = get_friends_followers_ids,print get_user_profile ( twitter_api , screen_names = [ “max_herbowy” ] ),és </ code> tagek- a , ,