android – twitter4j 401身份验证错误持久存取AccessToken
作者:互联网
我正在努力弄清楚发生了什么.我有一个典型的应用程序结构,它产生一个负责获取Twitter令牌的OAuthActivity,然后我的主应用程序活动将该令牌用于各种与twitter相关的操作.
我的OAuthActivity有效.我得到一个身份验证令牌,Twitter网页正确显示我的应用程序名称等….此外,在该活动中,我可以发送推文并发布. .这意味着OAuthActivity工作,时钟同步,令牌有效等等……
但是当这个OAuthActivity完成并返回到调用活动时,每当我尝试使用该标记(从持久化的密钥/秘密重新创建它)时,无论什么操作,操作总是会失败,并抱怨说AuthChallenge报告为null.就像我提供了一个空令牌,但我还没有!
请查看附件我的OAuthActivity的来源,以及我如何在主要活动中初始化Twitter对象的来源.如果你看错了,请告诉我.
PD – 我显然已经检查过我分配的令牌值与我得到的相同!还尝试了不同的方式来实例化Twitter,通过属性,通过构建器,通过集….并没有任何变化:(
编辑 – >我发现我必须在新的Twitter对象上调用“verifyCredentials()”,如果我想重用一个令牌,但是……没有运气! (请在最后找到发布的例外)
EDIT-2 – ;如果我同时使用子活动和父项
mTwitter=TwitterFactory.getSingleton()
然后twitter对象起作用,但这对我来说并不是真的可以接受,因为它不使用持久性,我需要每次都授权应用程序.此外,只有Twitter对象被授权,TwitterStream不断抛出异常.
干杯!
父活动的源代码,我尝试使用在子活动中获得的访问令牌,如下所示.无论我尝试使用此令牌,总是获得401.
private void init_twitter(String tok, String sec) {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(Conf.OAUTH_CONSUMER_KEY)
.setOAuthConsumerSecret(Conf.OAUTH_CONSUMER_SECRET)
.setOAuthAccessToken(tok)
.setOAuthAccessTokenSecret(sec);
TwitterFactory tf = new TwitterFactory(cb.build());
mTwitter=tf.getInstance();
/** This always fails, even though I call this routine with the
correct token & secret !!! See at the enf of message for an alternate
routine like this one that makes use of verifyCredentials and
also fails. */
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
mTwitter.updateStatus("yello 2");
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}).start();
}
孩子OAuthActivity的SOurce Code,显然是因为我获得了访问令牌&我能发推文:
import a lot;
public class TwitterLogin extends Activity {
private final String TAG = "TwitterLogin";
public final static String PREF_KEY_OAUTH_TOKEN="twitter.oauth.token", PREF_KEY_OAUTH_SECRET="twitter.oauth.secret", PREF_KEY_TWITTER_LOGIN="twitter.oauth.login";
private SharedPreferences mPreferences;
private Twitter twitter = new TwitterFactory().getInstance();
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "Starting task to retrieve request token.");
this.mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
super.onCreate(savedInstanceState);
getActionBar().setTitle("TWITTER AUTHENTICATION");
}
private void returnParent(boolean result) {
setResult(result?Activity.RESULT_OK:Activity.RESULT_CANCELED, null);
if (Conf.LOG_ON) Log.d(TAG, "TWITTER AUTH: END PROCESS , GLOBAL RESULT "+result);
/** THE FOLLOWING THING WORKS !!!!! IT SUCCESSFULLY TWEETS */
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
twitter.updateStatus("yello");
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}).start();
finish();
}
/**
* Uses TWITTER4J to get the Request URL. It gets something like
* AUTH URL TWITTER4J IS http://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxxxxxxxxxxxxxx
*
* @return The Request URL to open in webview and get the Verifier
*/
private String oauth_twitter4j_getRequestUrl() throws TwitterException {
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
RequestToken tempToken = twitter.getOAuthRequestToken(Constants.OAUTH_CALLBACK_URL);
return tempToken.getAuthorizationURL();
}
@Override
protected void onResume() {
super.onResume();
WebView webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
webview.setVisibility(View.VISIBLE);
setContentView(webview);
Log.i(TAG, "Retrieving request token from Google servers");
try {
StrictMode.ThreadPolicy policy = new StrictMode. ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);
String authorizationUrl=oauth_twitter4j_getRequestUrl();
Log.d(TAG, "AUTH URL TWITTER4J IS "+authorizationUrl_t);
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
if (Conf.LOG_ON) Log.d(TAG,"WebView: "+url);
if (url != null && url.startsWith(Constants.OAUTH_CALLBACK_URL)) try {
System.out.println("TWEET TWEET TWEET");
retrieveAccessToken(url); //added this
webView.setVisibility(View.GONE); //added this
return true;
} catch (Exception e) {
e.printStackTrace();
returnParent(false);
return true;
} else return false;
}
private void saveAccessToken(AccessToken accessToken) {
// Shared Preferences
Editor e = mPreferences.edit();
// After getting access token, access token secret
// store them in application preferences
e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
e.putString(PREF_KEY_OAUTH_SECRET,accessToken.getTokenSecret());
e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
e.commit();
Log.e("Twitter OAuth Token", "> " + accessToken.getToken()+"-"+accessToken.getScreenName());
}
private void retrieveAccessToken(String url) throws Exception {
String requestToken = extractParamFromUrl(url,"oauth_token");
String verifier= extractParamFromUrl(url,"oauth_verifier");
if (Conf.LOG_ON) Log.d(TAG, "Tenemos ACCESS TOKEN y VERIFIER :"+requestToken+","+verifier+","+(new Date().toString()));
if (ONLY_TWITTER4J)
retrieveAccessToken_with4j(verifier);
else
retrieveAccessToken_signpost(verifier);
}
private void retrieveAccessToken_with4j(String verifier) throws TwitterException {
AccessToken a=twitter.getOAuthAccessToken(verifier);
saveAccessToken(a);
returnParent(true);
}
private String extractParamFromUrl(String url,String paramName) {
String queryString = url.substring(url.indexOf("?", 0)+1,url.length());
QueryStringParser queryStringParser = new QueryStringParser(queryString);
return queryStringParser.getQueryParamValue(paramName);
}
});
webview.loadUrl(authorizationUrl);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
使用我确定正确的令牌调用VerifyCredentials时遇到的异常:
Received authentication challenge is null
W/System.err(24915): Relevant discussions can be found on the Internet at:
W/System.err(24915): http://www.google.co.jp/search?q=6f0f59ca or
W/System.err(24915): http://www.google.co.jp/search?q=20d0f74e
W/System.err(24915): TwitterException{exceptionCode=[6f0f59ca-20d0f74e 1de2170b-f94dee38], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.3}
W/System.err(24915): at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:192)
W/System.err(24915): at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
W/System.err(24915): at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:89)
W/System.err(24915): at twitter4j.TwitterBaseImpl.fillInIDAndScreenName(TwitterBaseImpl.java:126)
W/System.err(24915): at twitter4j.TwitterImpl.verifyCredentials(TwitterImpl.java:592)
W/System.err(24915): at com.regaliz.helpers.TwitterManager$2.run(TwitterManager.java:140)
W/System.err(24915): at java.lang.Thread.run(Thread.java:856)
W/System.err(24915): Caused by: java.io.IOException: Received authentication challenge is null
W/System.err(24915): at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:397)
W/System.err(24915): at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:345)
W/System.err(24915): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:276)
W/System.err(24915): at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
W/System.err(24915): at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:34)
W/System.err(24915): at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:156)
W/System.err(24915): ... 6 more
这是为了使用verifyCredentials而修改的函数:
private void init_twitter_2(final String tok, final String sec) throws TwitterException {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(Conf.OAUTH_CONSUMER_KEY)
.setOAuthConsumerSecret(Conf.OAUTH_CONSUMER_SECRET);
// .setOAuthAccessToken(tok)
// .setOAuthAccessTokenSecret(sec);
TwitterFactory tf = new TwitterFactory(cb.build());
mTwitter=tf.getInstance();
Log.d(TAG, "init_twitter_2 "+tok+","+sec);
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
User u;
try {
/** also tried setting token&secret like this, instead of in the builder-->no success */
mTwitter.setOAuthAccessToken(new AccessToken(tok,sec));
u = mTwitter.verifyCredentials();
Log.d(TAG, "User: "+u.getName());
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}).start();
}
解决方法:
有愚蠢的人,愚蠢的人,愚蠢的人,然后就是我.一个星期以来,我一直在努力寻找代码,追踪Twitter4j,用curl复制oauths,怀疑垃圾收集活动,追踪DDMS,计算令牌上的哈希……只是发现我有2个Conf.OAUTH_CONSUMER_xxxxx实例不同的价值观
由于这些东西来自常数,名字相似,我没有意识到.
感叹 – 50个声望指向厕所!
标签:twitter4j,android,authentication,token 来源: https://codeday.me/bug/20190831/1779090.html