【问题标题】:Android Tumblr Oauth-signpost 401Android Tumblr Oauth-signpost 401
【发布时间】:2011-12-12 02:51:21
【问题描述】:

好的,所以,我正在为 Android 制作一个 Tumblr 客户端,我一直在尝试并未能让 OAuth 工作大约一周。这是怎么回事:

用户启动应用程序。主要活动的 onCreate 这样做:

settings = getSharedPreferences(PREFS_NAME, 0);
authToken=settings.getString("OauthToken", "none");
authTokenSecret=settings.getString("OauthSecret", "none");
if(authToken=="none" || authTokenSecret=="none"){
    Intent i = new Intent(getApplicationContext(),Authentication.class);
    startActivity(i);
}

这会启动一个包含 WebView 的身份验证活动。该活动成功获取请求令牌,并将 WebView 发送到 Tumblr 登录屏幕。用户被要求允许应用程序访问他们的数据,他们按下允许,我的 WebViewClient 捕获回调 URL,并使用它执行此操作:

String[] token = helper.getVerifier(url);
            if (token != null) {
                try {
                    String accessToken[] = helper.getAccessToken(token[1]);
                    editor.putString("OauthToken", accessToken[0]);
                    editor.putString("OauthSecret", accessToken[1]);
                    editor.commit();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            finish();

帮助类的 getAccessToken 和 getVerifier 如下所示:

public String[] getVerifier(String myUrl) {
    // extract the token if it exists
    Uri uri = Uri.parse(myUrl);
    if (uri == null) {
        return null;
    }

    String token = uri.getQueryParameter("oauth_token");
    String verifier = uri.getQueryParameter("oauth_verifier");
    return new String[] { token, verifier };
}

public String[] getAccessToken(final String verifier)
        throws OAuthMessageSignerException, OAuthNotAuthorizedException,
        OAuthExpectationFailedException, OAuthCommunicationException {
    new Thread(new Runnable() {
        public void run() {
                try {
                    mProvider.retrieveAccessToken(mConsumer, verifier);
                } catch (OAuthMessageSignerException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (OAuthNotAuthorizedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (OAuthExpectationFailedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (OAuthCommunicationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }).start();
    return new String[] {
            mConsumer.getToken(), mConsumer.getTokenSecret()
    };
}

然后我终于回到主应用程序屏幕并尝试进行我的第一个 API 调用,以获取用户仪表板上最近的十个帖子:

OAuthConsumer myConsumer = new CommonsHttpOAuthConsumer(MainView.authToken, MainView.authTokenSecret);
            HttpGet request = new HttpGet("http://api.tumblr.com/v2/user/dashboard?limit=10");
            myConsumer.sign(request);
            HttpClient httpClient = new DefaultHttpClient();
            HttpResponse response = httpClient.execute(request);
            HttpEntity entity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }

但是,我没有得到应有的良好 JSON 响应,而是得到了这个:

10-20 16:36:18.110: D/Result(22817): {"meta":{"status":401,"msg":"Not Authorized"},"response":[]}

那么我哪里做错了?谢谢

【问题讨论】:

  • 我遇到了同样的问题,我尝试使用需要 POST 请求的 API 方法,但是 GET 请求似乎工作正常。我开始怀疑他们的 API 是否有点不稳定。
  • 你在开发什么版本的android?
  • 我也无法获取用户信息,获取令牌和秘密后的事件:(如果有人能为此提供解决方案,那就太好了。

标签: android oauth tumblr signpost


【解决方案1】:

我已经成功地将路标库与 Appache HttpCommons GET/POST/PUT 一起使用。

首先,我使用以下代码 (ActivityLogin.java) 启动了 WebView 进行登录:

private static CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET);
private static OAuthProvider provider = new DefaultOAuthProvider (AppConfig.requestURL, AppConfig.accessURL, AppConfig.authURL);

private void logMeIn() throws ...{
    String authUrl = provider.retrieveRequestToken(consumer,AppConfig.CALLBACK_URL);
    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
}

然后,我使用onNewIntent(Intent) 接收来自先前启动的Activity 的OAuth 回调:

AppConfig.java代码片段:

/** OAuth Authorization URL  */
public static final String authURL = mainOAuthUrl+"/authorize/?theme=android";

/** OAuth Request URL    */
public static final String requestURL = mainOAuthUrl+"/request/token/";

/** OAuth Access URL     */
public static final String accessURL = mainOAuthUrl+"/access/token/";

/** OAuth CALLback URL*/
public static final String CALLBACK_URL = "yourapp://twitt";

ActivityLogin.java代码片段:

protected void onNewIntent(Intent intent) {
    Uri uri = intent.getData();
    if (uri != null && uri.toString().startsWith(AppConfig.CALLBACK_URL)) {  
        String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);  

        provider.retrieveAccessToken(consumer, verifier);
        Data.OAuthAccessKey = consumer.getToken();
        Data.OAuthAccessSecret = consumer.getTokenSecret();
    }

}

然后,我的连接代码如下所示:

public HttpResponse sampleOauthConnect(String url) throws ...{

    /** setup some connection params */
    HttpContext context = new BasicHttpContext();

    HttpRequestBase request = new HttpGet(url);

    if (Data.OAuthConsumer == null)
        Data.OAuthConsumer = new CommonsHttpOAuthConsumer(AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET);

    if (Data.OAuthAccessKey == null || Data.OAuthAccessSecret == null)
        throw new LoginErrorException(LoginErrorException.NOT_LOGGED_IN);

    Data.OAuthConsumer.setTokenWithSecret(Data.OAuthAccessKey, Data.OAuthAccessSecret);

    try {
        Data.OAuthConsumer.sign(request);
    } catch (OAuthMessageSignerException e) {
        throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e);
    } catch (OAuthExpectationFailedException e) {
        throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e);
    } catch (OAuthCommunicationException e) {
        throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e);
    }

    HttpClient client = new DefaultHttpClient();

    /** finally execute this request */
    return client.execute(request, context);
}

我可能在复制粘贴过程中遗漏了一些内容,请告诉我此解决方案是否适合您。我正在使用 singpost 1.2.1.1

【讨论】:

  • 我现在没有时间测试你的代码,甚至在接下来的几天内。但是由于赏金快用完了,而且它看起来像是一个超级有用的详尽帖子,所以你赢了!谢谢,我稍后再看看它是否真的有效
  • 请记住,我在那里使用了两对密钥:AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET(存储在应用程序中)和Data.OAuthAccessKey, Data.OAuthAccessSecret,它们由服务器生成。
  • 未经授权获得相同的响应:{"meta":{"status":401,"msg":"Not Authorized"},"response":[]}
  • 这里有一个关于在 android 中使用路标登录 Tumblr 的完整教程:android-ios-tutorials.com/920/tumblr-login-using-sign-post
【解决方案2】:

目前Tumblr不支持MultipartEntity,所以你必须使用NameValuePairs来添加参数。

如果您想发布照片,则必须将该照片转换为 ARRAY 并对其进行 URL 编码!

【讨论】:

猜你喜欢
  • 2014-05-13
  • 2011-03-13
  • 2011-12-08
  • 2011-06-18
  • 2013-12-08
  • 2011-07-03
  • 2012-02-19
  • 2011-05-03
  • 2013-07-31
相关资源
最近更新 更多