GoogleBuzz

OAuth認証

GoogleのAPIではOAuth認証でアクセスできる。
OAuth for Web Applications

Tokenの取得

http://code.google.com/intl/ja/apis/buzz/v1/using_rest.html#authentication
Scopeは、以下の2つが使用できます。
  • https://www.googleapis.com/auth/buzz
  • https://www.googleapis.com/auth/buzz.readonly

認証方法は通常のものとほぼ同じですが、OAuthAuthorizeToken のフェーズではBuzz用のURLに変更する必要があります。
https://www.google.com/buzz/api/auth/OAuthAuthorizeToken
パラメータも scope と domainの設定が必要になります。
domainはアプリケーションのConsumerKeyを指定します。

Authorizationヘッダーへの設定

認証コードを使って署名をした情報をHttpヘッダに設定して、取得/投稿を行います。
署名で必要な情報は、TwitterなどのOAuthとほぼ一緒です。
ただ、oauth_version を付けていると認証がうまく通らないので、追加しないようにします。

ヘッダーには

OAuth oauth_signature="", oauth_token="", oauth_signature_method="", oauth_consumer_key="", oauth_timestamp="", oauth_nonce=""

という文字列をHttpヘッダの Authorization で設定します。
OAuth の文字の後に続くパラメータの順番は上記のとおりでなくて大丈夫。
oauth_token はエンコードした文字列を渡す必要があります。

Activity取得/投稿のコードサンプル

   // 以下は自分の値に置き換える ここから ----
   private static String ACCESS_TOKEN = "*******";
    private static String ACCESS_SECRET = "*******";
    private static String CONSUMER_KEY = "*******";
    private static String CONSUMER_SECRET = "*******";
   // ここまで ---
   
    private static String CONTENT_TYPE_JSON = "application/json;charset=UTF-8";
    private static String CONTENT_TYPE_XML = "application/atom+xml;charset=UTF-8";
 
   /**
     * ActivityList取得
     * @param alt xml | json
     * @param maxResults 取得件数
     * @throws java.io.IOException
     * @throws java.security.InvalidKeyException
     * @throws java.security.NoSuchAlgorithmException
     */
    private static void getActivities(String alt, int maxResults)
            throws IOException, InvalidKeyException, NoSuchAlgorithmException {

        String method = "GET";
        String baseUrl = "https://www.googleapis.com/buzz/v1/activities/@me/@consumption";
        String params = "alt=" + alt + "&max-results=" + maxResults;

        URL url = new URL(baseUrl + "?" + params);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod(method);

        Map<String, String> authParams = new LinkedHashMap<String, String>();
        authParams.put("alt", alt);
        authParams.put("max-results", String.valueOf(maxResults));
        addCommonParams(authParams);

        String authorizationHeader = getAuthorizationHeader(authParams, method, baseUrl);
        connection.addRequestProperty("Authorization", authorizationHeader);

        connection.connect();
        printResult(connection);
    }
   
    /**
     * Activityをポストする(JSON)
     * @param message
     */
    private static void postActivityByJson(String message) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
        String method = "POST";
        String baseUrl = "https://www.googleapis.com/buzz/v1/activities/@me/@self";
       
        URL url = new URL(baseUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod(method);

        Map<String, String> authParams = new LinkedHashMap<String, String>();
        addCommonParams(authParams);

        String authorizationHeader = getAuthorizationHeader(authParams, method, baseUrl);
        connection.addRequestProperty("Authorization", authorizationHeader);
        connection.setRequestProperty("Content-Type", CONTENT_TYPE_JSON);

        String postMessage = "{\"data\":{\"object\":{\"type\":\"note\",\"content\":\"" + message + "\"}}}";
        connection.setDoOutput(true);
        connection.getOutputStream().write(postMessage.getBytes(OAuthUtil.ENCODING));
        connection.getOutputStream().flush();
        connection.connect();
        printResult(connection);
    }

    /**
     * Activityをポストする(XML)
     * @param message
     */
    private static void postActivityByXML(String message) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
        String method = "POST";
        String baseUrl = "https://www.googleapis.com/buzz/v1/activities/@me/@self";
       
        URL url = new URL(baseUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod(method);
       
        Map<String, String> authParams = new LinkedHashMap<String, String>();
        addCommonParams(authParams);
       
        String authorizationHeader = getAuthorizationHeader(authParams, method, baseUrl);
        connection.addRequestProperty("Authorization", authorizationHeader);
        connection.setRequestProperty("Content-Type", CONTENT_TYPE_XML);
       
        String postMessage = "<?xml version='1.0' encoding='UTF-8'?><entry xmlns='http://www.w3.org/2005/Atom'><category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/sites/2008#creation' label='creation'/><atom:content xmlns:atom='http://www.w3.org/2005/Atom' type='text'>"
            + message + "</atom:content></entry>";
        connection.setDoOutput(true);
        connection.getOutputStream().write(postMessage.getBytes(OAuthUtil.ENCODING));
        connection.getOutputStream().flush();
        connection.connect();
        printResult(connection);
    }
   
   
    // **********************************************************************
   
    private static void addCommonParams(Map<String, String> authParams) {
        authParams.put("oauth_consumer_key", CONSUMER_KEY);
        authParams.put("oauth_nonce", String.valueOf((long) (Math.random() * Math.pow(2.0, 64.0))));
        authParams.put("oauth_signature_method", "HMAC-SHA1");
        authParams.put("oauth_timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        authParams.put("oauth_token", ACCESS_TOKEN);
    }
   
    private static String getAuthorizationHeader(Map<String, String> authParams, String method, String baseUrl) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
        String authParamsString = OAuthUtil.formatParamString(authParams);
        String sigBase = OAuthUtil.createSigBase(method, baseUrl, authParamsString);

        String key = OAuthUtil.encode(CONSUMER_SECRET) + "&" + OAuthUtil.encode(ACCESS_SECRET);
        String signature = OAuthUtil.createSignature(sigBase, key);

        StringBuilder authHeader = new StringBuilder();
        authHeader.append("OAuth");
        authHeader.append(" oauth_signature=\"").append(signature).append("\"");
        authHeader.append(", oauth_token=\"").append(OAuthUtil.encode(authParams.get("oauth_token"))).append("\"");
        authHeader.append(", oauth_signature_method=\"").append(authParams.get("oauth_signature_method")).append("\"");
        authHeader.append(", oauth_consumer_key=\"").append(authParams.get("oauth_consumer_key")).append("\"");
        authHeader.append(", oauth_timestamp=\"").append(authParams.get("oauth_timestamp")).append("\"");
        authHeader.append(", oauth_nonce=\"").append(authParams.get("oauth_nonce")).append("\"");
        System.out.println(authHeader.toString());
        return authHeader.toString();
    }
   
    /**
     * 結果を標準出力に出力
     * @param connection
     * @throws IOException
     */
    private static void printResult(HttpURLConnection connection) throws IOException {
        System.out.println("response code=" + connection.getResponseCode());
        InputStream input = null;
        if (connection.getResponseCode() == 200) {
            input = connection.getInputStream();
        } else {
            input = connection.getErrorStream();
        }
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        String value = "";
        while ((value = reader.readLine()) != null) {
            System.err.println(value);
        }
    }

OAuthUtil.java

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class OAuthUtil {
    public static final String ENCODING = "UTF-8";
    public static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";

    /**
     * sigBaseを作成
     * @param method
     * @param url
     * @param params
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String createSigBase(String method, String url, String params) throws UnsupportedEncodingException {
        return method.toUpperCase() + "&" + URLEncoder.encode(url, ENCODING) + "&"
                + URLEncoder.encode(params, ENCODING);
    }

    /**
     * 署名
     * @param data
     * @param key
     * @return
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.InvalidKeyException
     */
    public static String createSignature(String data, String key) throws NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
        mac.init(signingKey);
        return byteArrayToBase64(mac.doFinal(data.getBytes()));
    }

    /**
     * エンコードする
     * @param value
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String encode(String value) throws UnsupportedEncodingException {
        return URLEncoder.encode(value, ENCODING);
    }

    /**
     * パラメータを文字列に変換
     * @param params
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String formatParamString(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder b = new StringBuilder();
        boolean first = true;
        for (String key : params.keySet()) {
            if (!first) {
                b.append("&");
            }
            first = false;
            b.append(key).append("=").append(encode(params.get(key)));
        }
        return b.toString();
    }

    static String byteArrayToBase64(byte[] bytes) {
        int aLen = bytes.length;
        int numFullGroups = aLen / 3;
        int numBytesInPartialGroup = aLen - 3 * numFullGroups;
        int resultLen = 4 * ((aLen + 2) / 3);
        StringBuilder b = new StringBuilder(resultLen);

        int inCursor = 0;
        for (int i = 0; i < numFullGroups; i++) {
            int byte0 = bytes[inCursor++] & 0xff;
            int byte1 = bytes[inCursor++] & 0xff;
            int byte2 = bytes[inCursor++] & 0xff;
            b.append(intToBase64[byte0 >> 2]);
            b.append(intToBase64[(byte0 << 4) & 0x3f | (byte1 >> 4)]);
            b.append(intToBase64[(byte1 << 2) & 0x3f | (byte2 >> 6)]);
            b.append(intToBase64[byte2 & 0x3f]);
        }

        if (numBytesInPartialGroup != 0) {
            int byte0 = bytes[inCursor++] & 0xff;
            b.append(intToBase64[byte0 >> 2]);
            if (numBytesInPartialGroup == 1) {
                b.append(intToBase64[(byte0 << 4) & 0x3f]);
                b.append("==");
            } else {
                int byte1 = bytes[inCursor++] & 0xff;
                b.append(intToBase64[(byte0 << 4) & 0x3f | (byte1 >> 4)]);
                b.append(intToBase64[(byte1 << 2) & 0x3f]);
                b.append('=');
            }
        }
        return b.toString();
    }

    static final char intToBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
            'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', '+', '/' };

}
Comments