Android的OAuth的:异常的retrieveAccessToken()异常、Android、OAuth、retrieveAccessToken

2023-09-03 22:00:25 作者:转身后的回眸

我设立的OAuth我的Andr​​oid应用程序。为了测试它,我做了以下内容: 新增指路牌核-1.2.1.1.jar和路标,commonshttp4-1.2.1.1.jar到我的项目,增加了变量CommonsHttpOAuthConsumer消费和CommonsHttpOAuthProvider提供者,做单击该按钮时,以下内容:

I'm setting up OAuth for my Android app. To test it I did the following: Added signpost-core-1.2.1.1.jar and signpost-commonshttp4-1.2.1.1.jar to my project, added the variables "CommonsHttpOAuthConsumer consumer" and "CommonsHttpOAuthProvider provider" and did the following when the button is clicked:

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()进行以下操作:

persistOAuthData() does the following:

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()方法,我加载提供者和消费者数据,并执行以下操作:

In the onResume() method I load the provider and consumer data and do the following:

    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(消费者,验证)失败,并OAuthCommunicationException说:与服务提供者的通信失败:空。

So, what works: 1) I do get a requestToken and a requestSecret. 2) I do get the oauthUrl. 3) I am directed to the browser page to authorize my app 4) I am getting redirected to my app. 5) I do get the verifier. But calling retrieveAccessToken(consumer, verifier) fails with an OAuthCommunicationException saying "Communication with the service provider failed: null".

有谁知道可能是什么原因呢?有些人似乎都得到requestToken问题,但只是正常工作。我不知道这可能是一个问题,我的应用程序还包括了Apache-mime4j-0.6.jar和httpmime-4.0.1.jar,我需要多部分上传。

Does anyone know what might be the reason? Some people seem to have problems getting the requestToken, but that just works fine. I wonder if it might be a problem that my app has also included the apache-mime4j-0.6.jar and httpmime-4.0.1.jar which I need for multipart upload.

推荐答案

好吧,我理解了它。也许这就是帮助他人:

Okay, I figured it out. Maybe this is helpful to others:

首先,你不需要保存整个消费者和提供者的对象。所有你需要做的是存储requestToken和requestSecret。幸运的是,这些都是字符串,所以你并不需要将它们写入到磁盘或任何东西。只要将它们存储在共享preferences或类似的东西。

First of all, you do not need to save the whole consumer and provider object. All you need to do is store the requestToken and the requestSecret. Luckily, those are Strings, so you don't need to write them to disk or anything. Just store them in the sharedPreferences or something like that.

现在,当您通过浏览器重定向和你的onResume()方法被调用,只要做到以下几点:

Now, when you get redirected by the browser and your onResume() method is called, just do the following:

//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()的秘密吧。

That's it, you can receive the token and the secret with getToken() and getTokenSecret(), now.