Android OAuth:retrieveAccessToken()上的异常

时间:2010-07-15 11:37:21

标签: android twitter oauth signpost

我正在为我的Android应用设置OAuth。为了测试它我做了以下: 将signpost-core-1.2.1.1.jar和signpost-commonshttp4-1.2.1.1.jar添加到我的项目中,添加变量“CommonsHttpOAuthConsumer consumer”和“CommonsHttpOAuthProvider provider”,并在单击按钮时执行以下操作:

consumer = new CommonsHttpOAuthConsumer("xxx", "yyy");
provider = new CommonsHttpOAuthProvider("https://api.twitter.com/oauth/request_token", 
                    "https://api.twitter.com/oauth/access_token", 
                    "https://api.twitter.com/oauth/authorize");

oauthUrl = provider.retrieveRequestToken(consumer, "myapp://twitterOauth");
persistOAuthData();
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(oauthUrl)));

persistOAuthData()执行以下操作:

protected void persistOAuthData()
{
    try
    {
        FileOutputStream providerFOS = this.openFileOutput("provider.dat", MODE_PRIVATE);
        ObjectOutputStream providerOOS = new ObjectOutputStream(providerFOS);
        providerOOS.writeObject(this.provider);
        providerOOS.close();

        FileOutputStream consumerFOS = this.openFileOutput("consumer.dat", MODE_PRIVATE);
        ObjectOutputStream consumerOOS = new ObjectOutputStream(consumerFOS);
        consumerOOS.writeObject(this.consumer);
        consumerOOS.close();
    }
    catch (Exception e) { }
}

因此,在打开浏览器之前会保存使用者和提供者,如here所述。

在onResume()方法中,我加载提供者和消费者数据并执行以下操作:

    Uri uri = this.getIntent().getData();
    if (uri != null && uri.getScheme().equals("myapp") && uri.getHost().equals("twitterOauth"))
    {
        verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
        if (!verifier.equals(""))
        {
            loadOauthData();
            try
            {
                provider.retrieveAccessToken(consumer, verifier);
            }
            catch (OAuthMessageSignerException e) {
                e.printStackTrace();
            } catch (OAuthNotAuthorizedException e) {
                e.printStackTrace();
            } catch (OAuthExpectationFailedException e) {
                e.printStackTrace();
            } catch (OAuthCommunicationException e) {
                e.printStackTrace();
            }            
        }
    }

那么,什么有效: 1)我得到一个requestToken和一个requestSecret。 2)我确实得到了oauthUrl。 3)我被引导到浏览器页面来授权我的应用程序 4)我被重定向到我的应用程序。 5)我确实得到了验证者。 但调用retrieveAccessToken(使用者,验证者)失败,并显示“与服务提供者的通信失败:null”的OAuthCommunicationException。

有谁知道可能是什么原因?有些人似乎在获取requestToken时遇到了问题,但这样做效果很好。我想知道我的应用程序是否也包含apache-mime4j-0.6.jar和httpmime-4.0.1.jar这可能是一个问题,我需要进行分段上传。

2 个答案:

答案 0 :(得分:13)

好的,我明白了。也许这对其他人有帮助:

首先,您不需要保存整个使用者和提供者对象。您需要做的就是存储requestToken和requestSecret。幸运的是,这些是字符串,因此您不需要将它们写入磁盘或任何东西。只需将它们存储在sharedPreferences或类似的东西中。

现在,当您通过浏览器重定向并调用onResume()方法时,只需执行以下操作:

//The consumer object was lost because the browser got into foreground, need to instantiate it again with your apps token and secret.
consumer = new CommonsHttpOAuthConsumer("xxx", "yyy"); 

//Set the requestToken and the tokenSecret that you got earlier by calling retrieveRequestToken.
consumer.setTokenWithSecret(requestToken, tokenSecret);

//The provider object is lost, too, so instantiate it again.
provider = new CommonsHttpOAuthProvider("https://api.twitter.com/oauth/request_token", 
                                "https://api.twitter.com/oauth/access_token", 
                                "https://api.twitter.com/oauth/authorize");     
//Now that's really important. Because you don't perform the retrieveRequestToken method at this moment, the OAuth method is not detected automatically (there is no communication with Twitter). So, the default is 1.0 which is wrong because the initial request was performed with 1.0a.
provider.setOAuth10a(true);

provider.retrieveAccessToken(consumer, verifier);

就是这样,你现在可以通过getToken()和getTokenSecret()接收令牌和秘密。

答案 1 :(得分:0)

嗨Manuel我看到你也在OAuthocalypse中避免! heres是一个很好的例子,使用sharedPreferences来保存requestToken和requestSecret,就像你的解决方案一样,为Twitter实现OAuth。 http://github.com/brione/Brion-Learns-OAuth 作者:Brion Emde

继承人video

希望这有助于其他开发者=)