8

我正在为我的 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) { }
}

因此,消费者和提供者在打开浏览器之前被保存,如此所述。

在 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(consumer, verifier) 失败并出现OAuthCommunicationException 说“与服务提供者的通信失败:null”。

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

4

2 回答 2

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() 接收令牌和秘密。

于 2010-07-15T13:19:50.247 回答
0

嗨,曼努埃尔,我看到你也在避免 OAuthocalypse!heres 是使用 sharedPreferences 为 Twitter 实现 OAuth 以保存 requestToken 和 requestSecret 的一个很好的示例,就像您的解决方案一样。 http://github.com/brione/Brion-Learns-OAuth 由 Brion Emde

这是视频

希望这可以帮助其他开发人员 =)

于 2010-07-15T18:11:14.703 回答