,

Twitter oauth

成り行きでandroidtwitterのoauthに挑戦することにしました.twitter4jが良さげということになったのですが、成り行き上、生JSONが必要でした.そこでtwitter4jはtokenを取得するためだけに使って、署名は自前で生成してHTTPConnectionを使うことにしました.
どうもうまくいかないと思ったらtokenとsecretを間違えて代入していました.
ということでOAuthの認証ヘッダーの生成はこんな感じ

  String consumer_key, consumer_secret, token, token_secret; //何かはわかりますよね
  String getAuthorization(String u, String m){
	  long timestamp = (new Date()).getTime()/1000L;
	  String nonce = ""+(timestamp*timestamp);  //適当で良い(ランダム)
      return getAuthorization(u, m, nonce, timestamp);	  
  }
  //引数にu: urlを指定
  String getAuthorization(String u, String method, String nonce, long timestamp){
	  if(token == null) return null;
          //まずはURLを分解してqueryを取り出す
	  StringTokenizer s = new StringTokenizer(u, "?");
	  String base_uri = s.nextToken();
	  ArrayList query = new ArrayList();
	  if(s.hasMoreTokens()){
		  StringTokenizer st = new StringTokenizer(s.nextToken(),"&");
		  while(st.hasMoreTokens()){ query.add(st.nextToken());}
	  }
          //次にoauthのqueryを足す
	  query.add("oauth_consumer_key="+consumer_key);
	  query.add("oauth_nonce="+nonce);
	  query.add("oauth_signature_method=HMAC-SHA1");
	  query.add("oauth_token="+token);
	  query.add("oauth_timestamp="+timestamp);
	  query.add("oauth_version=1.0");
	  Object[] oa = query.toArray();
          //sortして署名対象のテキストを生成
	  Arrays.sort(oa);   
	  StringBuffer sb = new StringBuffer(method);
	  sb.append("&");
	  sb.append(URLEncoder.encode(base_uri));
	  sb.append("&");
	  for(int i = 0; i < oa.length; i ++){ 
		  sb.append(URLEncoder.encode( ( String ) oa[i]));
		  if(i < oa.length -1) sb.append("%26");
	  }
	  System.out.println("String to sign:"+sb.toString());
	try {
          //署名の作成
	  Key key = new SecretKeySpec*1;
		mac.init(key);
		String sign = BASE64Encoder.encode(mac.doFinal(sb.toString().getBytes())); //twitter4j.internal.http.BASE64Encoder
           //署名はBase64エンコードされたものをさらにエンコードして使う
		query.add("oauth_signature="+URLEncoder.encode(sign));  
		oa = query.toArray(); Arrays.sort(oa); //このソートはいらないかも
           //認証用のヘッダーを生成
		sb = new StringBuffer("OAuth ");
		for(int i = 0; i < oa.length; i ++){
			String oai = (String)oa[i];
			  if(oai.startsWith("oauth")){
				  int oaii = oai.indexOf("=");
				  sb.append(oai.substring(0, oaii+1));sb.append("\"");
				  sb.append(oai.substring(oaii+1));sb.append("\",");
			  }
		}
	  sb.delete(sb.length()-1, sb.length());
	  return sb.toString();
	} catch (NoSuchAlgorithmException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (InvalidKeyException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	  return null;
  }

*1:consumer_secret+"&"+token_secret).getBytes(), "HmacSHA1"); Mac mac = Mac.getInstance(key.getAlgorithm(