在Twitter API上获取401代码

时间:2014-12-16 15:42:20

标签: java twitter oauth twitter-oauth

由于未知原因,我在oAuth代码上获得了 401代码,以便在Streaming Twitter API上进行连接。我对每个方法进行了三重检查,但我找不到错误。我在互联网上搜索OAuth参数或Twitter API参数,但没有运气。这是代码:

package Configuration;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;

public class OAuth {

private URL     URL_BASE;
private String  oauth_token;
private String  oauth_method;
private String  oauth_version;
private String  oauth_consumer_key;
private String  con_method;

public OAuth() throws MalformedURLException {
    this.con_method = "POST";
    this.URL_BASE   = new URL("https://stream.twitter.com/1.1/statuses/filter.json");

    this.oauth_consumer_key = "XXXXXXX";
    this.oauth_token        = "XXXXXXX";
    this.oauth_method       = "HMAC-SHA1";
    this.oauth_version      = "1.0";
}

/**
 * Timestamp
 * 
 * The oauth_timestamp parameter indicates when the request was created.
 * This value should be the number of seconds since the Unix epoch at the
 * point the request is generated, and should be easily generated in most
 * programming languages. Twitter will reject requests which were created
 * too far in the past, so it is important to keep the clock of the
 * computer generating requests in sync with NTP.
 * 
 * @see oauth_timestamp 1318622958
 */
public String oauth_timestamp() {
    long millis = System.currentTimeMillis();
    long secs   = millis / 1000;

    return String.valueOf(secs);
}

/**
 * Nonce
 * 
 * The oauth_nonce parameter is a unique token your application should generate
 * for each unique request. Twitter will use this value to determine whether a
 * request has been submitted multiple times. The value for this request was
 * generated by base64 encoding 32 bytes of random data, and stripping out all
 * non-word characters, but any approach which produces a relatively random
 * alphanumeric string should be OK here.
 * 
 * @see oauth_nonce kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg
 */
public String oauth_nounce() {
    SecureRandom rdn = new SecureRandom();

    String nounce_1 = new BigInteger(130, rdn).toString(32);
    String nounce_2 = new BigInteger(130, rdn).toString(32).substring(0, 6);

    if((new String(nounce_1 + nounce_2)).length() != 32)
        System.out.println("Tamanho do nounce incorreto");

    return nounce_1 + nounce_2;
}

/**
 * Signature
 * 
 * The oauth_signature parameter contains a value which is generated by
 * running all of the other request parameters and two secret values
 * through a signing algorithm. The purpose of the signature is so that
 * Twitter can verify that the request has not been modified in transit,
 * verify the application sending the request, and verify that the
 * application has authorization to interact with the user’s account.
 * @throws NoSuchAlgorithmException 
 * @throws InvalidKeyException 
 * 
 * @see oauth_signature tnnArxj06cWHq44gCs1OSKk/jLY=
 */
private String oauth_signature(String message) throws NoSuchAlgorithmException, InvalidKeyException {
    Mac sha1 = Mac.getInstance("HmacSHA1");

    sha1.init(new SecretKeySpec("CONSUMER_SECRET".getBytes(), "HmacSHA1"));
    sha1.update(message.getBytes());

    return URLEncoder.encode(String.valueOf(Base64Coder.encode(sha1.doFinal())));
}

public String authenticate() throws InvalidKeyException, MalformedURLException, IOException, NoSuchAlgorithmException {

    StringBuffer buffer  = new StringBuffer();
    String       charset = "UTF-8";
    String       read;

    String[][] data = 
        {
            {"oauth_consumer_key"    , this.oauth_consumer_key  },
            {"oauth_nonce"           , oauth_nounce()           },
            {"oauth_signature"       , ""                       },
            {"oauth_signature_method", this.oauth_method        },
            {"oauth_timestamp"       , oauth_timestamp()        },
            {"oauth_token"           , this.oauth_token         },
            {"oauth_version"         , this.oauth_version       }
        };

    String sg_base_str = "POST&"+URLEncoder.encode(this.URL_BASE.toString(),charset)+"&";

    for(int i = 0; i < data.length; i++)
    {
        String _26;

        if(data.length + 1 < i)
             _26 = "%26";
        else _26 = "";

        if(data[i][0] != "oauth_signature")
        {
            sg_base_str += URLEncoder.encode(data[i][0],charset) + "%3D"
                        +  URLEncoder.encode(data[i][1],charset) + _26 ;
        }
    }

    data[2][1] = oauth_signature(sg_base_str);

    String header = "OAuth ";

    for(String[] item : data) 
        header += item[0]+"=\""+item[1]+"\", ";

    // cut off last appended comma
    header = header.substring(0, header.length()-2);

    System.out.println("Signature Base String:\n\n" + sg_base_str + "\n");
    System.out.println( "Authorization Header:\n\n" + header      + "\n\n");

    System.setProperty("http.keepAlive", "true");
    HttpsURLConnection con = (HttpsURLConnection) this.URL_BASE.openConnection();
    con.setInstanceFollowRedirects(true);

    con.setDoInput (true);
    con.setDoOutput(true);

    con.setRequestMethod  (this.con_method);
    con.setRequestProperty("Accept"         , "*/*");
    con.setRequestProperty("Connection"     , "close");
    con.setRequestProperty("Content-Type"   , "application/x-www-form-urlencoded");
    con.setRequestProperty("Accept-Charset" , charset);
    con.setRequestProperty("User-Agent"     , "JMiner v1.0");
    con.setRequestProperty("Content-length" , "0");
    con.setRequestProperty("Host"           , "api.twitter.com");
    con.setRequestProperty("Authorization"  , header);

    OutputStream output = con.getOutputStream();
    output.write( header.getBytes(charset) );

    BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));

    while((read = reader.readLine()) != null)
        buffer.append(read);

   return buffer.toString();
 }
}

0 个答案:

没有答案