P3に組み込むべく、作ってみた。オリジナルはid:tototoshiの「request tokenを取得するJavaプログラム」。
実際にはここから更に手を加えることになると思うのだけど、とりあえずご参考ということで。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import java.util.UUID; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class AccessToken { private static final String CONSUMER_KEY = "xxxxxxxxxxxxxx"; private static final String CONSUMER_SECRET = "xxxxxxxxxxxxxxxxxxxxxx"; private static final String SIGNATURE_METHOD = "HMAC-SHA1"; private static final String OAUTH_VERSION = "1.0"; private static final String ALGOTITHM = "HmacSHA1"; private Map<String, String> parameterMap; private SortedMap<String, String> oauthParametersMap; private boolean useProxy = false; private String method = null; private String api = null; private String oauthToken; private String oauthTokenSecret; public AccessToken(String method, String api, Map<String, String> parameterMap) { this.method = method; this.api = api; this.parameterMap = parameterMap; } public String get(){ return oauthToken; } public String getSecret(){ return oauthTokenSecret; } public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); try { map.put("x_auth_mode", SignatureEncode.encode"client_auth")); map.put("x_auth_password", SignatureEncode.encode"パスワード")); map.put("x_auth_username", SignatureEncode.encode"スクリーンネーム")); } catch (UnsupportedEncodingException ignore) { } AccessToken accessToken = new AccessToken( "POST", "https://api.twitter.com/oauth/access_token", map); accessToken.request(); System.out.println(accessToken.get()); System.out.println(accessToken.getSecret()); } public void request() { setProperty(); oauthParametersMap = createParametersMap(); HttpURLConnection urlconn = null; BufferedReader reader = null; try { String apiParamter = createParameters(); URL url = new URL(api + (apiParamter.length() > 0 ? "?" + apiParamter : "")); urlconn = (HttpURLConnection) url.openConnection(); urlconn.setRequestMethod(method); urlconn.addRequestProperty("Authorization", createAuthorizationValue()); urlconn.connect(); if (urlconn.getResponseCode() == HttpURLConnection.HTTP_OK) { reader = new BufferedReader(new InputStreamReader(urlconn.getInputStream())); String line = reader.readLine(); System.out.println(line); String[] parameters = line.split("&"); for (String parameter : parameters) { String[] keyAndValue = parameter.split("="); if (keyAndValue.length < 2) { continue; } String key = keyAndValue[0]; String value = keyAndValue[1]; if("oauth_token".equals(key)){ oauthToken = value; }else if("oauth_token_secret".equals(key)){ oauthTokenSecret = value; } } } else { urlconn.disconnect(); } } catch (IOException e) { // "Read Time out"; e.printStackTrace(); } catch (InvalidKeyException ignore) { } catch (NoSuchAlgorithmException ignore) { }finally{ if (reader != null) { try { reader.close(); } catch (IOException ignore) { } } if (urlconn != null) { urlconn.disconnect(); } } } private void setProperty() { System.setProperty("sun.net.client.defaultReadTimeout", "15000"); System.setProperty("sun.net.client.defaultConnectTimeout", "15000"); if(useProxy){ System.setProperty("http.proxyHost", "proxyServerName"); System.setProperty("http.proxyPort", "proxyPortNo"); }else{ System.setProperty("http.nonProxyHosts", "localhost"); } } private SortedMap<String, String> createParametersMap() { SortedMap<String, String> map = new TreeMap<String, String>(); map.put("oauth_consumer_key", CONSUMER_KEY); map.put("oauth_nonce", UUID.randomUUID().toString()); map.put("oauth_signature_method", SIGNATURE_METHOD); map.put("oauth_timestamp", getTimeStamp()); map.put("oauth_version", OAUTH_VERSION); return map; } private String createParameters() { if (parameterMap == null || parameterMap.size() == 0) { return ""; } StringBuilder builder = new StringBuilder(); for (Map.Entry<String, String> param : parameterMap.entrySet()) { builder.append(param.getKey() + "="); builder.append(param.getValue()); builder.append("&"); } return builder.toString().substring(0, builder.length() -1); } private String createAuthorizationValue() throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException { StringBuilder builder = new StringBuilder(); builder.append("OAuth "); for (Map.Entry<String, String> param : oauthParametersMap.entrySet()) { builder.append(param.getKey() + "="); builder.append("\"" + param.getValue() + "\","); } builder.append("oauth_signature" + "="); builder.append("\"" + getSignature(getSignatureBaseString(), getKey()) + "\""); return builder.toString(); } private String getKey() { StringBuilder builder = new StringBuilder(); builder.append(CONSUMER_SECRET); builder.append("&"); return builder.toString(); } private String getRequestParameters() { if (parameterMap != null && parameterMap.size() > 0) { for (Map.Entry<String, String> param : parameterMap.entrySet()) { oauthParametersMap.put(param.getKey(), param.getValue()); } } StringBuilder builder = new StringBuilder(); for (Map.Entry<String, String> param : oauthParametersMap.entrySet()) { builder.append(param.getKey()); builder.append("="); builder.append(param.getValue()); builder.append("&"); } return builder.toString().substring(0, builder.length() -1); } private String getSignatureBaseString() throws UnsupportedEncodingException { return method + "&" + encodeURL(api) + "&" + SignatureEncode.encode(getRequestParameters()); } private String getSignature(String signatureBaseString, String keyString) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException{ Mac mac = Mac.getInstance(ALGOTITHM); Key key= new SecretKeySpec(keyString.getBytes(), ALGOTITHM); mac.init(key); byte[] digest = mac.doFinal(signatureBaseString.getBytes()); return encodeURL(Base64.encodeBytes(digest)); } private String encodeURL(String str) { String encord = null; try { encord = URLEncoder.encode(str, "UTF-8"); } catch (UnsupportedEncodingException ignore) { } return encord; } private String getTimeStamp() { return Long.toString(System.currentTimeMillis() / 1000); } }
import java.io.UnsupportedEncodingException; public class SignatureEncode { private static final String UNRESERVEDCHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; public static final String encode(String s) throws UnsupportedEncodingException { byte[] bytes = s.getBytes("utf-8"); StringBuffer builder = new StringBuffer(); for (byte b: bytes){ char c = (char) b; if (UNRESERVEDCHARS.indexOf(String.valueOf(c)) >= 0) { builder.append(String.valueOf(c)); } else { builder.append("%" + String.valueOf(Integer.toHexString(b > 0 ? b : b + 256)).toUpperCase()); } } return builder.toString(); } }
id:tototoshiと@aki_null,@kiri_featherに千の感謝を。
あと、おかしな所とか、気づかれたことがありましたらご指摘ください。
【追記】
プロキシ環境下だとOauthが通らない、という話があるけど、これならどうだろうか…