安卓系统:Twitter oAuth出现OAuthNotAuthorizedException错误



我想使用Twitter oAuth。我看过不同的例子和教程。所以我从头开始。我已经在dev.twitter.com,上注册了申请,没关系。提供消费者密钥和消费者机密。

然后,我将signpost-coresignpost-commonhttp jar添加到我的libs文件夹中,并定义了如下常量:

private static final String CONSUMER_KEY = "myConsumerKey";
private static final String CONSUMER_SECRET = "myConsumerSecretKey";
private static String ACCESS_KEY = null;
private static String ACCESS_SECRET = null;
private static final String REQUEST_URL = "http://twitter.com/oauth/request_token";
private static final String ACCESS_TOKEN_URL = "http://twitter.com/oauth/access_token";
private static final String AUTH_URL = "http://twitter.com/oauth/authorize";
private static final String CALLBACK_URL = "OauthTwitter://twitter";
private static final String PREFERENCE_FILE = "twitter_oauth.prefs"
private static CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(
            CONSUMER_KEY, CONSUMER_SECRET);
private static CommonsHttpOAuthProvider provider = new CommonsHttpOAuthProvider(
REQUEST_URL, ACCESS_TOKEN_URL, AUTH_URL);

这是我的清单:

<data android:scheme="OauthTwitter" android:host="twitter"/>

最后是我的点击事件:

try {
    String authURL = provider.retrieveRequestToken(consumer, CALLBACK_URL);
    Log.d("OAuthTwitter", authURL);
    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authURL)));
} catch (OAuthMessageSignerException e) {
    e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
    e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
    e.printStackTrace();
} catch (OAuthCommunicationException e) {
    e.printStackTrace();
}   

当我点击按钮时,我看到了这个轨迹:

07-23 06:24:48.428: W/System.err(15121): oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match.
07-23 06:24:48.433: W/System.err(15121):    at oauth.signpost.AbstractOAuthProvider.handleUnexpectedResponse(AbstractOAuthProvider.java:243)
07-23 06:24:48.433: W/System.err(15121):    at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:193)
07-23 06:24:48.433: W/System.err(15121):    at oauth.signpost.AbstractOAuthProvider.retrieveRequestToken(AbstractOAuthProvider.java:74)
07-23 06:24:48.438: W/System.err(15121):    at com.exampel.app.MyActivity$1.onClick(MyActivity.java:71)
07-23 06:24:48.438: W/System.err(15121):    at android.view.View.performClick(View.java:2364)
07-23 06:24:48.438: W/System.err(15121):    at android.view.View.onTouchEvent(View.java:4179)
07-23 06:24:48.438: W/System.err(15121):    at android.widget.TextView.onTouchEvent(TextView.java:6541)
07-23 06:24:48.443: W/System.err(15121):    at android.view.View.dispatchTouchEvent(View.java:3709)
07-23 06:24:48.443: W/System.err(15121):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
07-23 06:24:48.443: W/System.err(15121):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
07-23 06:24:48.448: W/System.err(15121):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
07-23 06:24:48.448: W/System.err(15121):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
07-23 06:24:48.448: W/System.err(15121):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1665)
07-23 06:24:48.448: W/System.err(15121):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
07-23 06:24:48.453: W/System.err(15121):    at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
07-23 06:24:48.453: W/System.err(15121):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1649)
07-23 06:24:48.453: W/System.err(15121):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1694)
07-23 06:24:48.458: W/System.err(15121):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-23 06:24:48.458: W/System.err(15121):    at android.os.Looper.loop(Looper.java:123)
07-23 06:24:48.458: W/System.err(15121):    at android.app.ActivityThread.main(ActivityThread.java:4363)
07-23 06:24:48.463: W/System.err(15121):    at java.lang.reflect.Method.invokeNative(Native Method)
07-23 06:24:48.463: W/System.err(15121):    at java.lang.reflect.Method.invoke(Method.java:521)
07-23 06:24:48.463: W/System.err(15121):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
07-23 06:24:48.463: W/System.err(15121):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
07-23 06:24:48.468: W/System.err(15121):    at dalvik.system.NativeStart.main(Native Method)

我对钥匙和秘密很确定,但还是一样。我做错了什么?任何建议都很好。

首先,我必须指定您的代码和答案看起来都很好,但不确定为什么不起作用。在其他地方,我在初始化TwitterFactory时使用ConfigurationBuilder

它看起来像:

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
    .setOAuthConsumerKey("ConsumerKey")
    .setOAuthConsumerSecret("ConsumerSecret");
try {
    Twitter twitter = new TwitterFactory(cb.build()).getInstance();
    requestToken = twitter.getOAuthRequestToken("application://calback");
    WebView twitterSite = new WebView(MyActivity.this);
    twitterSite.loadUrl(requestToken.getAuthenticationURL());
    setContentView(twitterSite);                    
} catch (Exception e) {
    e.printStackTrace();
}

然后要小心你的<data>定义。该标签应位于<intent-filter>中。

如果仍然出现错误,请重新设置一次。我希望这能解决你的问题。

从twitter开发者帐户重置密钥,然后重试。。我有同样的问题和补种后的关键问题解决了。

使用此url

 public static final String REQUEST_URL = "http://api.twitter.com/oauth/request_token";
 public static final String ACCESS_URL = "http://api.twitter.com/oauth/access_token";
 public static final String AUTHORIZE_URL = "http://api.twitter.com/oauth/authorize";

public static final String OAUTH_CALLBACK_SCHEME = "x-oauthflow-twitter";
 public static final String OAUTH_CALLBACK_HOST  = "callback";
 public static final String OAUTH_CALLBACK_URL  = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;

我在点击Twitter验证时使用了这个。。

Intent i = new Intent(getApplicationContext(), PrepareRequestTokenActivity.class);
                finish();
                startActivity(i);

这是PrepareRequestTokenActivity.java

package com.twitter;
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import com.WFBOS.SettingActivity;
/**
 * Prepares a OAuthConsumer and OAuthProvider 
 * 
 * OAuthConsumer is configured with the consumer key & consumer secret.
 * OAuthProvider is configured with the 3 OAuth endpoints.
 * 
 * Execute the OAuthRequestTokenTask to retrieve the request, and authorize the request.
 * 
 * After the request is authorized, a callback is made here.
 * 
 */
public class PrepareRequestTokenActivity extends Activity 
{
    final String TAG = getClass().getName();
    private OAuthConsumer consumer; 
    private OAuthProvider provider;
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        try
        {
            this.consumer = new CommonsHttpOAuthConsumer(Constants1.CONSUMER_KEY, Constants1.CONSUMER_SECRET);
            this.provider = new CommonsHttpOAuthProvider(Constants1.REQUEST_URL,Constants1.ACCESS_URL,Constants1.AUTHORIZE_URL);
        }
        catch (Exception e)
        {
            Log.e(TAG, "Error creating consumer / provider",e);
        }
        Log.i(TAG, "Starting task to retrieve request token.");
        new OAuthRequestTokenTask(this,consumer,provider).execute();
    }
    /**
     * Called when the OAuthRequestTokenTask finishes (user has authorized the request token).
     * The callback URL will be intercepted here.
     */
    @Override
    public void onNewIntent(Intent intent)
    {
        super.onNewIntent(intent); 
        SharedPreferences prefs = getSharedPreferences("Twitter", MODE_PRIVATE);
        final Uri uri = intent.getData();
        if (uri != null && uri.getScheme().equals(Constants1.OAUTH_CALLBACK_SCHEME)) 
        {
            Log.i(TAG, "Callback received : " + uri);
            Log.i(TAG, "Retrieving Access Token");
            new RetrieveAccessTokenTask(this,consumer,provider,prefs).execute(uri);
            finish();   
        }
    }
    public class RetrieveAccessTokenTask extends AsyncTask<Uri, Void, Void> 
    {
        private Context context;
        private OAuthProvider provider;
        private OAuthConsumer consumer;
        private SharedPreferences prefs;
        public RetrieveAccessTokenTask(Context context, OAuthConsumer consumer,OAuthProvider provider, SharedPreferences prefs)
        {
            this.context = context;
            this.consumer = consumer;
            this.provider = provider;
            this.prefs=prefs;
        }

        /**
         * Retrieve the oauth_verifier, and store the oauth and oauth_token_secret 
         * for future API calls.
         */
        @Override
        protected Void doInBackground(Uri...params)
        {
            final Uri uri = params[0];
            final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
            try 
            {
                provider.retrieveAccessToken(consumer, oauth_verifier);
                final Editor edit1 = prefs.edit();
                edit1.putString(OAuth.OAUTH_TOKEN, consumer.getToken());
                edit1.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret());
                edit1.commit();
                String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
                String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
                Log.d("toker", token);
                Log.d("Secret", secret);
                consumer.setTokenWithSecret(token, secret);
                context.startActivity(new Intent(context,SettingActivity.class));
                //executeAfterAccessTokenRetrieval();
                Log.i(TAG, "OAuth - Access Token Retrieved");
            } 
            catch (Exception e)
            {
                Log.e(TAG, "OAuth - Access Token Retrieval Error", e);
            }
            return null;
        }

        /*private void executeAfterAccessTokenRetrieval()
        {
            String msg = getIntent().getExtras().getString("tweet_msg");
            try
            {
                TwitterUtils.sendTweet(prefs, msg);
            } 
            catch (Exception e)
            {
                Log.e(TAG, "OAuth - Error sending to Twitter", e);
            }
        }*/
    }   
}

这是OAuthRequestTokenTask.java

package com.twitter;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
/**
 * An asynchronous task that communicates with Twitter to 
 * retrieve a request token.
 * (OAuthGetRequestToken)
 * 
 * After receiving the request token from Twitter, 
 * pop a browser to the user to authorize the Request Token.
 * (OAuthAuthorizeToken)
 * 
 */
public class OAuthRequestTokenTask extends AsyncTask<Void, Void, Void> 
{
    final String TAG = getClass().getName();
    private Context context;
    private OAuthProvider provider;
    private OAuthConsumer consumer;
    /**
     * 
     * We pass the OAuth consumer and provider.
     * 
     * @param   context
     *          Required to be able to start the intent to launch the browser.
     * @param   provider
     *          The OAuthProvider object
     * @param   consumer
     *          The OAuthConsumer object
     */
    public OAuthRequestTokenTask(Context context,OAuthConsumer consumer,OAuthProvider provider)
    {
        this.context = context;
        this.consumer = consumer;
        this.provider = provider;
    }
    /**
     * 
     * Retrieve the OAuth Request Token and present a browser to the user to authorize the token.
     * 
     */
    @Override
    protected Void doInBackground(Void... params) 
    {
        try
        {
            Log.i(TAG, "Retrieving request token from Google servers");
            final String url = provider.retrieveRequestToken(consumer, Constants1.OAUTH_CALLBACK_URL);
            Log.i(TAG, "Popping a browser with the authorize URL : " + url);
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
            context.startActivity(intent);
        } 
        catch (Exception e) 
        {
            Log.e(TAG, "Error during OAUth retrieve request token", e);
        }
        return null;
    }
}

这是我的Constant1.java

package com.twitter;
public class Constants1
{
    public static final String CONSUMER_KEY = "your key";
    public static final String CONSUMER_SECRET= "your key";

    public static final String REQUEST_URL = "http://api.twitter.com/oauth/request_token";
    public static final String ACCESS_URL = "http://api.twitter.com/oauth/access_token";
    public static final String AUTHORIZE_URL = "http://api.twitter.com/oauth/authorize";
    public static final String  OAUTH_CALLBACK_SCHEME   = "x-oauthflow-twitter";
    public static final String  OAUTH_CALLBACK_HOST     = "callback";
    public static final String  OAUTH_CALLBACK_URL      = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;
    //public static final String    OAUTH_CALLBACK_URL      = "http://www.wfbos.com";
}

我有非常相似的代码,但得到了相同的错误。通过将我的测试手机设置为使用网络的日期/时间设置,我可以让事情正常进行。显然,如果您的设备的日期/时间设置不正确,可能会导致此问题。

最新更新