【问题标题】:Android OAuth: Exception on retrieveAccessToken()Android OAuth:retrieveAccessToken() 上的异常
【发布时间】:2011-03-16 08:54:48
【问题描述】:

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

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

【问题讨论】:

    标签: android twitter oauth signpost


    【解决方案1】:

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

    这是video

    希望这对其他开发者有所帮助 =)

    【讨论】:

      【解决方案2】:

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

      首先,您不需要保存整个消费者和提供者对象。您需要做的就是存储 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() 接收令牌和秘密了。

      【讨论】:

      • 所以在您的情况下,您在consumer.setOkenWithSecret 中设置的requestTokenoauthUrl?请问tokenSecret 是什么?谢谢:)
      • 对不起,我想我可能想通了,requestToken 是使用consumer.getToken() 检索到的吗?
      猜你喜欢
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      • 2017-07-30
      相关资源
      最近更新 更多