1

我正在尝试允许 Android 用户使用我的应用发布到他们的 Tumblr 博客。我能够启动 Tumblr,输入我的用户名和密码,然后登录,但问题是我收到的访问令牌似乎无效(当我将它与任何 Tumblr 的 API 调用一起使用时,我得到一个 401 - 未经授权)。

下面是我正在使用的代码。我可以通过 Twitter 进行身份验证,但 Tumblr 给我带来了困难。如果有人有任何想法、建议或改进,他们将不胜感激。谢谢!

public final class TumblrWebView extends Activity {
    private final String TAG = getClass().getSimpleName();
    OAuth10Service service;

    public final static String PARAMETER_CONSUMER_KEY = "CONSUMER_KEY";
    public final static String PARAMETER_CONSUMER_SECRET = "CONSUMER_SECRET";
    public final static String PARAMETER_CALLBACK_URL = "CALLBACK_URL";

    private String consumerKey;
    private String consumerSecret;
    private String callbackUrl;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web_view);

        /*
         * Get params
         */
        Intent intent = getIntent();
        consumerKey = intent.getStringExtra(PARAMETER_CONSUMER_KEY);
        consumerSecret = intent.getStringExtra(PARAMETER_CONSUMER_SECRET);
        callbackUrl = intent.getStringExtra(PARAMETER_CALLBACK_URL);

        service = OAuthService.newInstance(new TumblrApi(), consumerKey, consumerSecret, new OAuth10ServiceCallback() {

            @Override
            public void onOAuthAccessTokenReceived(OAuth10Token token) {
                complete(token);

                Log.i(TAG, "Access token recieved");
                //  System.out.println("token recieved " + token.getAccessToken());
                //  System.out.println("token recieved " + token.getUserSecret());
            }

            @Override
            public void onOAuthRequestTokenReceived() {
                loadWebView();

                Log.i(TAG, "Request token recieved");
            }

            @Override
            public void onOAuthRequestTokenFailed(HootResult result) {
                Log.e(TAG, "Token request failed " + result.getException());
            }

            @Override
            public void onOAuthAccessTokenFailed(HootResult result) {
                Log.e(TAG, "Token access failed " + result);
            }

        });
        service.start();
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void loadWebView() {
        final WebView webview = (WebView) findViewById(R.id.web_view);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                // Checking for our successful callback
                if(url.startsWith(callbackUrl)) {
                    webview.setVisibility(View.GONE);
                    Log.d(TAG, "token url " + url + " " + service.getOAuthAccessToken(url));
                } else {
                    Log.d(TAG, "token url");
                }
                return super.shouldOverrideUrlLoading(view, url);
            }

        });

        webview.loadUrl(service.getAuthorizeUrl());
    }

    private void complete(OAuth10Token token) {
        Intent resultIntent = new Intent();
        resultIntent.putExtra(TumblrUtils.PREF_TUMBLR_ACCESS, token.getAccessToken());
        resultIntent.putExtra(TumblrUtils.PREF_TUMBLR_SECRET, token.getUserSecret());
        setResult(RESULT_OK, resultIntent);
        finish();
    }
}

编辑:一个助手类

public class TumblrUtils {

    // Consumer Key and Secret
    private static final String TUMBLR_CONSUMER_KEY    = "{ ENTER TUMBLR CONSUMER KEY }";
    private static final String TUMBLR_CONSUMER_SECRET = "{ ENTER TUMBLR CONSUMER SECRET }";

    // Callback URL
    private static final String TUMBLR_CALLBACK_URL = "http://example.com";

    // Request Code
    public static final int TUMBLR_REQUEST_CODE = 87; /* 87 - TR */

    // Preference Constants
    public static final String PREF_TUMBLR_USER     = "tumblr_user";
    public static final String PREF_TUMBLR_ACCESS   = "tumblr_access_token";
    public static final String PREF_TUMBLR_SECRET   = "tumblr_secret_token";

    public static final String TUMBLR_REQUEST_URL   = "http://www.tumblr.com/oauth/request_token";
    public static final String TUMBLR_ACCESS_URL    = "http://www.tumblr.com/oauth/access_token";
    public static final String TUMBLR_AUTHORIZE_URL = "http://www.tumblr.com/oauth/authorize";

    private static OAuthConsumer tumblrConsumer;
    private static String tumblrHost;
    private static String tumblrToken;
    private static String tumblrTokenSecret;

    private static String getConsumerKey() {
        return TUMBLR_CONSUMER_KEY;
    }

    private static String getConsumerSecret() {
        return TUMBLR_CONSUMER_SECRET;
    }

    private static String getCallbackUrl() {
        return TUMBLR_CALLBACK_URL;
    }

    public static String getRequestUrl() {
        return TUMBLR_REQUEST_URL;
    }

    public static String getAccessUrl() {
        return TUMBLR_ACCESS_URL;
    }

    public static String getAuthorizeUrl() {
        return TUMBLR_AUTHORIZE_URL;
    }

    public static OAuthConsumer getTumblrConsumer() {
        return tumblrConsumer;
    }

    public static String getTumblrHost() {
        return tumblrHost;
    }

    public static void setTumblrHost(String host) {
        TumblrUtils.tumblrHost = host;
    }

    public static String getTumblrToken() {
        return tumblrToken;
    }

    public static String getTumblrTokenSecret() {
        return tumblrTokenSecret;
    }

    public static Intent getTumblrIntent(Context activity) {
        Intent TumblrIntent = new Intent(activity,  TumblrWebView.class);
        TumblrIntent.putExtra("CONSUMER_KEY",       getConsumerKey());
        TumblrIntent.putExtra("CONSUMER_SECRET",    getConsumerSecret());
        TumblrIntent.putExtra("CALLBACK",           getCallbackUrl());
        return TumblrIntent;
    }

    public static OAuthConsumer saveTumblrResult(SharedPreferences settings, 
            String access_token, String secret_token) {
        Editor editor = settings.edit();
        editor.putString(PREF_TUMBLR_ACCESS, access_token);
        editor.putString(PREF_TUMBLR_SECRET, secret_token);
        editor.commit();
        return saveTumblrResult(access_token, secret_token);
    }

    public static OAuthConsumer saveTumblrResult(String stringExtra1, String stringExtra2) {
        tumblrToken       = (stringExtra1);
        tumblrTokenSecret = (stringExtra2);
        tumblrConsumer = new CommonsHttpOAuthConsumer(
                getConsumerKey(), getConsumerSecret());
        tumblrConsumer.setTokenWithSecret(
                tumblrToken, tumblrTokenSecret);
        return tumblrConsumer;
    }

}

编辑:TumblrWebActivity - startActivityForResult

startActivityForResult(
TumblrUtils.getTumblrIntent(Settings_ShareSettings.this), 

编辑:TumblrWebActivity - onActivityResult

TumblrUtils.TUMBLR_REQUEST_CODE);
TumblrUtils.saveTumblrResult(mPrefs,
    data.getStringExtra(TumblrUtils.PREF_TUMBLR_ACCESS),
    data.getStringExtra(TumblrUtils.PREF_TUMBLR_SECRET));
new TumblrTask("https://api.tumblr.com/v2/user/info").execute();

编辑:GetUserInfo - AsyncTask

private final class TumblrTask extends AsyncTask<String, Void, String> {

    String url;

    public TumblrTask(String url) {
        this.url = url;
    }

    @Override
    protected String doInBackground(String... params) {
        String result = "";
        HttpClient httpclient = GlobalContext.getHttpClient();

        HttpRequestBase request = new HttpGet(url);

        try {
            TumblrUtils.getTumblrConsumer().sign(request);
        } catch (OAuthMessageSignerException e) {
            e.printStackTrace();
        } catch (OAuthExpectationFailedException e) {
            e.printStackTrace();
        } catch (OAuthCommunicationException e) {
            e.printStackTrace();
        }

        try {
            HttpResponse response = httpclient.execute(request, GlobalContext.getLocalContext());
            HttpEntity entity = response.getEntity();
            InputStream instream = entity.getContent();
            result = GlobalContext.convertStreamToString(instream);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            JSONObject jObject = new JSONObject(result.trim());
            System.out.println(jObject);

            if(jObject.has("response")) {
                JSONObject jResponse = jObject.getJSONObject("response");
                System.out.println(jResponse);

                if(jResponse.has("user")) {
                    JSONObject jUser = jResponse.getJSONObject("user");
                    System.out.println(jUser);

                    tumblr_name = jUser.getString("name");
                    TumblrUtils.saveTumblrResult(mPrefs, tumblr_name);
                    tvTumblr.setText(tumblr_name);
                    ibTumblr.setSelected(true);
                }
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

编辑:注意:需要 AndrOAuth

4

1 回答 1

0

事实证明,返回的访问令牌和访问令牌秘密是有效的。问题是我没有使用 Access Token Secret 签署请求。

于 2013-08-02T22:20:59.883 回答