Search code examples
twittertwitter-oauthtwitter4j

Error on getting authorization URL more than once in Twitter4j


I'm using Twitter4j to implement the authorization workflow on my webapp (user acesses a page, twitter asks permission, I receive the callback and generate the oauth access token).

My first problem was that if I called a method to get the Twitter sigleton:

Twitter twitter = TwitterFactory.getSingleton();
twitter.setOAuthConsumer(getClientId(), getClientSecret());

1) Since OAuthConsumer would already be defined I would get an exception. And I can't find how to ask the singleton if it already has the credentials defined. What's the best way? My solution was to save the singleton in a private member...

2) Now I want to generate an AuthorizationURL, so I need to ask Twitter singleton the OAuthRequestToken:

RequestToken oauthRequestToken = twitter.getOAuthRequestToken(getCallbackURL()); //FIXME

And this throws an exception:

401:Authentication credentials (https://dev.twitter.com/pages/auth) were missing or incorrect. Ensure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync.
message - Invalid or expired token.
code - 89


Relevant discussions can be found on the Internet at:
 http://www.google.co.jp/search?q=3cc69290 or
 http://www.google.co.jp/search?q=45a986a5
TwitterException{exceptionCode=[3cc69290-45a986a5], statusCode=401, message=Invalid or expired token., code=89, retryAfter=-1, rateLimitStatus=null, version=4.0.4}
 at twitter4j.HttpClientImpl.handleRequest(HttpClientImpl.java:164)
 at twitter4j.HttpClientBase.request(HttpClientBase.java:57)
 at twitter4j.HttpClientBase.post(HttpClientBase.java:86)
 at twitter4j.auth.OAuthAuthorization.getOAuthRequestToken(OAuthAuthorization.java:115)
 at twitter4j.auth.OAuthAuthorization.getOAuthRequestToken(OAuthAuthorization.java:92)
 at twitter4j.TwitterBaseImpl.getOAuthRequestToken(TwitterBaseImpl.java:292)
 at twitter4j.TwitterBaseImpl.getOAuthRequestToken(TwitterBaseImpl.java:287)
 (...)

Note: the 'Relevant discussions' links are not working as expected I think...

In short:

1) How can I ask the singleton if it already has the credentials defined in order to 'setOAuthConsumer' doesn't throw an error ?

2) How to re-ask the singleton to generate a new authorizationURL for the user to access and authorize (again) ?

Also posted in the corresponding forum


Solution

  • The solution I've found is presented here:

    Twitter instance = new TwitterFactory().getInstance();
    instance.setOAuthConsumer(getClientId(), getClientSecret());
    RequestToken requestToken = new RequestToken(getOauthToken(),getOauthTokenSecret());
    AccessToken oAuthAccessToken = instance.getOAuthAccessToken(requestToken, oauthVerifier);
    

    requestTokenand oauthVerifier are received as parameters in the callback. getOauthToken() and getOauthTokenSecret() retrieve the tokens retrieved by the library in the first step and that were saved in a cache (user -> tokens).

    Inspired by this question/answers: Having multiple Twitter instances with twitter4j library.