マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

OAuthのアプリケーションの許可画面がでるまで

http://d.hatena.ne.jp/tototoshi/20100117を参考にRequestTokeを取得して、アプリケーションを許可するかどうかの確認画面をAndroid上で行うプログラムを書いた。DesireではまだBase64が使えないためhttp://iharder.sourceforge.net/current/java/base64/を利用した。あらかじめhttp://twitter.com/oauth_clientsでアプリケーションを登録してConsumer keyとConsumer secretを登録しておくこと。RequestTokenまで取得する付トログラムと、それを利用するActivityのソースコードを載せておく。以下ソースコード

package test.oauth;

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;

import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;

import java.security.Key;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class RequestToken {
    private static final String REQUEST_TOKEN_URL = "http://twitter.com/oauth/request_token";
    private static final String SIGNATURE_METHOD = "HMAC-SHA1";
    private static final String OAUTH_VERSION = "1.0";
    
    private String oauthToken;
    private String oauthTokenSecret;
    
    private RequestToken(){
        
    }
    
    public String getToken(){
        return oauthToken;
    }
    
    public String getSecret(){
        return oauthTokenSecret;
    }

    
    public static RequestToken getRequestToken(String consumerKey, String consumerSecret) throws IOException{
        RequestToken token = new RequestToken();
        token.request(consumerKey, consumerSecret);
        
        return token;
    }

    private void request(String consumerKey, String consumerSecret) throws IOException{
        String requestParameters = RequestToken.getRequestParameter(consumerKey, consumerSecret);
        String signatureBaseString = RequestToken.getSignatureBaseString(requestParameters); 
        String keyString = getKeyString(consumerSecret);
        String signature = getSignature(signatureBaseString, keyString);

        String request = REQUEST_TOKEN_URL + "?" + requestParameters + "&oauth_signature=" + signature;
        System.out.println(request);
        String response = RequestToken.getLine(request);
        
        String[] parameters = response.split("&");

        for(String parameter : parameters){
            String[] keyValue = parameter.split("=");

            String key = keyValue[0];
            String value = keyValue[1];
            
            if("oauth_token".equals(key)){
                oauthToken = value;
            }else if("oauth_token_secret".equals(key)){
                oauthTokenSecret = value;
            }

        }
    }
    
    private static String getRequestParameter(String consumerKey, String consumerSecret){
        StringBuilder parameters = new StringBuilder(100);
        
        parameters.append("oauth_consumer_key=");
        parameters.append(consumerKey).append('&');
        parameters.append("oauth_nonce=");
        parameters.append(RequestToken.createRandomString(10)).append('&');
        parameters.append("oauth_signature_method=");
        parameters.append(SIGNATURE_METHOD).append('&');
        parameters.append("oauth_timestamp=");
        parameters.append(System.currentTimeMillis() / 1000).append('&');
        parameters.append("oauth_version=").append(OAUTH_VERSION);
        
        return parameters.toString();
    }
    
    private static String getSignatureBaseString(String requestParameters) {
        return "GET&" + RequestToken.tryURLEncode(REQUEST_TOKEN_URL) + "&" + RequestToken.tryURLEncode(requestParameters);
    }

    private static String tryURLEncode(String str){
        String urlEncode = null;
        
        try{
            urlEncode = URLEncoder.encode(str, "UTF-8");
        }catch(UnsupportedEncodingException e){
            throw new RuntimeException(e.getMessage(), e);
        }
        
        return urlEncode;
    }
    
    private String getKeyString(String cosumerSecret){  
        if(oauthToken == null){
            return cosumerSecret + "&";
        }else{
            return cosumerSecret + "&" + oauthToken;
        }
    }

    private static String getSignature(String signatureBaseString, String keyString){
        String signature = null;
        String algorithm = "HmacSHA1";
        
        try {
            Mac mac = Mac.getInstance(algorithm);
            Key key= new SecretKeySpec(keyString.getBytes(), algorithm);
            mac.init(key);
            
            byte[] digest = mac.doFinal(signatureBaseString.getBytes());
            signature = RequestToken.tryURLEncode(Base64.encodeBytes((digest)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage(), e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        
        return signature;
    }

    
    private static String createRandomString(int length){
        StringBuilder randomString = new StringBuilder(length);
        
        for(int i = 0; i < length; i++){
            randomString.append((char)('a' + (int)Math.floor(Math.random() * 26)));
        }
        
        return randomString.toString();
    }
    
    private static String getLine(String request) throws IOException{
        URL url = new URL(request);
        URLConnection connection = url.openConnection();
        BufferedReader br = null;
        String line = null;
        
        try{
            br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            line = br.readLine();
        }catch(IOException e){
            try{
                if(br != null){
                    br.close();
                }

                e.printStackTrace();
            }catch(IOException ioe){
                throw ioe;
            }
        }
        
        return line;
    }
}
package test.oauth;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.webkit.WebView;
import java.io.IOException;

public class OAuthActivity extends Activity {
    private static final String CONSUMER_KEY = "XXXxxxXXXxxx";
    private static final String CONSUMER_SECRET = "YYYXXXYYY";
    private static final String TOKEN_PAGE = "http://twitter.com/oauth/authorize?oauth_token=";
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try{
            RequestToken token = RequestToken.getRequestToken(CONSUMER_KEY, CONSUMER_SECRET);
            String oauthToken = token.getToken();
            String secret = token.getSecret();
            
            WebView view = new WebView(this);
            view.loadUrl(TOKEN_PAGE + oauthToken);
            setContentView(view);
        }catch(IOException e){
            e.printStackTrace();
            new AlertDialog.Builder(this).setTitle("エラー").setMessage(e.getMessage()).show();
        }
    }
}