yasuoza diary

web and life

scribe-java in Android

Famous OAuth libraries for Android are

There are entries about how to make OAuth authentication using oauth-signpost but I could not find any example using scribe-java, even though it is said

Scribe is a mature OAuth library for Java by Pablo Fernandez that is intended to work with all APIs

http://oauth.net/code/

The following example is how to make OAuth 1.0a authentication using scribe-java.

First, create oauth api model:

api/TwitterApi.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class TwitterApi extends DefaultApi10a {
  private static final String AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize?oauth_token=%s";
  private static final String REQUEST_TOKEN_RESOURCE = "api.twitter.com/oauth/request_token";
  private static final String ACCESS_TOKEN_RESOURCE = "api.twitter.com/oauth/access_token";

  @Override {
  public String getAccessTokenEndpoint()
    return "http://" + ACCESS_TOKEN_RESOURCE;
  }

  @Override
  public String getRequestTokenEndpoint() {
    return "http://" + REQUEST_TOKEN_RESOURCE;
  }

  @Override
  public String getAuthorizationUrl(Token requestToken) {
    return String.format(AUTHORIZE_URL, requestToken.getToken());
  }

  public static class SSL extends TwitterApi {
    @Override
    public String getAccessTokenEndpoint() {
      return "https://" + ACCESS_TOKEN_RESOURCE;
    }

    @Override
    public String getRequestTokenEndpoint() {
      return "https://" + REQUEST_TOKEN_RESOURCE;
    }
  }

  /**
   * Twitter 'friendlier' authorization endpoint for OAuth.
   *
   * Uses SSL.
   */
  public static class Authenticate extends SSL {
    private static final String AUTHENTICATE_URL = "https://api.twitter.com/oauth/authenticate?oauth_token=%s";

    @Override
    public String getAuthorizationUrl(Token requestToken) {
      return String.format(AUTHENTICATE_URL, requestToken.getToken());
    }
  }

  /**
   * Just an alias to the default (SSL) authorization endpoint.
   *
   * Need to include this for symmetry with 'Authenticate' only.
   */
  public static class Authorize extends SSL{}
}

(Retrieved from scribe/builder/api/TwitterApi.java. You can build your own api model like this.)

Then, use this api model in your Activity with WebView :

OauthActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public class OauthActivity extends Activity {

    private static final String CALLBACK_URL = "http://www.twitter.com";

    private WebView mWebView;
    private OauthService mOauthService;
    private Token mRequestToken;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mService = new ServiceBuilder()
          .provider(TwitterApi.class)
          .apiKey("YOUR_API_KEY")
          .apiSecret("YOUR_API_SECRET")
          .callback(HatenaApi.CALLBACK_URL)
          .build();

        mWebView = (WebView) findViewById(R.id.webView);
        mWebView.clearCache(true);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setBuiltInZoomControls(true);
        mWebView.getSettings().setDisplayZoomControls(false);
        mWebView.setWebViewClient(mWebViewClient);
        mWebView.setWebChromeClient(mWebChromeClient);

        setContentView(mWebView);

        startAuthorize();
    }

    private void startAuthorize() {
        (new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                mRequestToken = mService.getRequestToken();
                return mService.getAuthorizationUrl(mRequestToken);
            }

            @Override
            protected void onPostExecute(String url) {
                mWebView.loadUrl(url);
            }
        }).execute();
    }

    private WebViewClient mWebViewClient = new WebViewClient() {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            if ((url != null) && (url.startsWith(CALLBACK_URL))) { // Override webview when user came back to CALLBACK_URL
                mWebView.stopLoading();
                mWebView.setVisibility(View.INVISIBLE); // Hide webview if necessary
                Uri uri = Uri.parse(url);
                final Verifier verifier = new Verifier(uri.getQueryParameter("oauth_verifier"));
                (new AsyncTask<Void, Void, Token>() {
                    @Override
                    protected Token doInBackground(Void... params) {
                        return mService.getAccessToken(mRequestToken, verifier);
                    }

                    @Override
                    protected void onPostExecute(Token accessToken) {
                        // AccessToken is passed here! Do what you want!
                        finish();
                    }
                }).execute();
            } else {
                super.onPageStarted(view, url, favicon);
            }
        }
    };
}

Yeah! You’ve done! It’s easy isn’t it?

Keypoints are

  • Build service
  • Get request token
  • Get authorize url
  • Get verifier
  • Get access token based on the verifier

Comments