2015-05-30 19 views
5

Ben folowing dizisi ile Java tarafından oauth uygulamak am ve oauth_callback_confirmed = trueHeyecan oauth geçersiz oauth_verifier parametresi

2) https sayfasına yönlendiriliyorsunuz:? //api.twitter.com/oauth/authenticate oauth_token = {twitter dan önceki yanıttan oauth_token}

3) Heyecan giriş formu görünür

, ben tıklayın düğme "giriş".

4) Heyecan {callback_url} yönlendirir oauth_token = & oauth_verifier = {doğrulayıcı}

5) POST https {bu belirteç oauth/request_token yanıt belirteci eşittir}: //api.twitter.com/oauth Geçersiz oauth_verifier parametresini

oauth_verifier nesi var:/Oauth başlığıyla access_token Hata OAuth isteği işlenirken = ileti gövdesi oauth_verifier = {döndü doğrulayıcı}

6) Heyecan yanıtını içeren, oauth_token içerir?

hesaplayın imza yöntemi: İlk istek için

private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException { 
     SecretKey secretKey = null; 

     byte[] keyBytes = keyString.getBytes(); 
     secretKey = new SecretKeySpec(keyBytes, "HmacSHA1"); 

     Mac mac = Mac.getInstance("HmacSHA1"); 
     mac.init(secretKey); 

     byte[] text = baseString.getBytes(); 

     return new String(Base64.encodeBase64(mac.doFinal(text))).trim(); 
    } 

Kodu:

String oauth_signature_method = "HMAC-SHA1"; 

    // generate any fairly random alphanumeric string as the "nonce". 
    String uuid_string = UUID.randomUUID().toString(); 
    uuid_string = uuid_string.replaceAll("-", ""); 
    String oauth_nonce = uuid_string; 

    // get the timestamp 
    Calendar tempcal = Calendar.getInstance(); 
    long ts = tempcal.getTimeInMillis(); 
    String oauth_timestamp = (new Long(ts/1000)).toString(); 
    String parameter_string = "oauth_callback=" + OauthConstants.TWITTER_OAUTH_CALLBACK 
      + "&oauth_consumer_key=" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY 
      + "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=" 
      + oauth_signature_method + "&oauth_timestamp=" + oauth_timestamp + "&oauth_version=1.0"; 
    String signature_base_string = get_or_post + "&" + encode(twitter_endpoint) + "&" + encode(parameter_string); 
    String oauth_signature = ""; 

    try { 
     oauth_signature = computeSignature(signature_base_string, OauthConstants.TWITTER_OAUTH_CONSUMER_SECRET + "&"); 
    } catch (GeneralSecurityException | UnsupportedEncodingException e) { 
     ...} 

String twitter_endpoint = "https://api.twitter.com/oauth/request_token"; 
String authorization_header_string = "OAuth oauth_callback=\"" + OauthConstants.TWITTER_OAUTH_CALLBACK 
       + "\",oauth_consumer_key=\"" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY 
       + "\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"" + oauth_timestamp 
       + "\",oauth_nonce=\"" + oauth_nonce + "\",oauth_version=\"1.0\",oauth_signature=\"" 
       + encode(oauth_signature) + "\""; 

// Apache httpcore 4.4.1 
HttpProcessor httpproc = HttpProcessorBuilder.create() 
       .add(new RequestContent()) 
       .add(new RequestTargetHost()) 
       .add(new RequestConnControl()) 
       .add(new RequestUserAgent("ApacheHttp/1.1")) 
       .add(new RequestExpectContinue(true)).build(); 

     HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); 
     HttpCoreContext context = HttpCoreContext.create(); 
     HttpHost host = new HttpHost(twitter_endpoint_host, 443); 
     DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024); 

     context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); 
     context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host); 

try { 
       // initialize the HTTPS connection 
       SSLContext sslcontext = SSLContext.getInstance("TLS"); 
       sslcontext.init(null, null, null); 
       SSLSocketFactory ssf = sslcontext.getSocketFactory(); 
       Socket socket = ssf.createSocket(); 
       socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), 0); 
       conn.bind(socket); 

       BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest("POST", twitter_endpoint_path, HttpVersion.HTTP_1_1); 
       request2.setEntity(new StringEntity("", "UTF-8")); 
       request2.addHeader("Authorization", authorization_header_string); 
       httpexecutor.preProcess(request2, httpproc, context); 
       HttpResponse response2 = httpexecutor.execute(request2, conn, context); 
       httpexecutor.postProcess(response2, httpproc, context); 
} catch(Exception e) {} ... 

Kod ikinci istek için (oauth/authenticate https'ye yönlendir) 3 istek için

public JSONObject getTwitterAuthorizationCodeFromRequestToken(String oauth_token) { 
... 
     String twitter_endpoint = "https://api.twitter.com/oauth/authenticate"; 

     ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
     try { 
      FacesContext.getCurrentInstance().getExternalContext().redirect(twitter_endpoint + "?oauth_token=" + encode(oauth_token)); 
     } catch (IOException ex) {...} 
... 
    } 

Kodu (POST oauth/access_token)

public JSONObject getTwitterAccessTokenFromAuthorizationCode(String verifier_or_pin, String oauth_token) { 
    ... 
String oauth_signature_method = "HMAC-SHA1"; 

    // generate any fairly random alphanumeric string as the "nonce". Nonce = Number used ONCE. 
    String uuid_string = UUID.randomUUID().toString(); 
    uuid_string = uuid_string.replaceAll("-", ""); 
    String oauth_nonce = uuid_string; 

    Calendar tempcal = Calendar.getInstance(); 
    long ts = tempcal.getTimeInMillis(); 
    String oauth_timestamp = (new Long(ts/1000)).toString(); 

    // the parameter string must be in alphabetical order 
    String parameter_string = "oauth_consumer_key=" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY 
          + "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=" + oauth_signature_method 
          + "&oauth_timestamp=" + oauth_timestamp + "&oauth_token=" + encode(oauth_token) + "&oauth_version=1.0"; 

    String signature_base_string = get_or_post + "&" + encode(twitter_endpoint) + "&" + encode(parameter_string); 

    String oauth_signature = ""; 
    try { 
     oauth_signature = computeSignature(signature_base_string, OauthConstants.TWITTER_OAUTH_CONSUMER_SECRET + "&"); 
    } catch (GeneralSecurityException | UnsupportedEncodingException e) { 
     ... 
    } 

    String authorization_header_string = "OAuth oauth_consumer_key=\"" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY 
               + "\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"" + oauth_timestamp 
               + "\",oauth_nonce=\"" + oauth_nonce + "\",oauth_version=\"1.0\",oauth_signature=\"" 
               + encode(oauth_signature) + "\",oauth_token=\"" + encode(oauth_token) + "\""; 

    HttpProcessor httpproc = HttpProcessorBuilder.create() 
        .add(new RequestContent()) 
        .add(new RequestTargetHost()) 
        .add(new RequestConnControl()) 
        .add(new RequestUserAgent("ApacheHttp/1.1")) 
        .add(new RequestExpectContinue(true)).build(); 

      HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); 
      HttpCoreContext context = HttpCoreContext.create(); 
      HttpHost host = new HttpHost(twitter_endpoint_host, 443); 
      DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024); 

      context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); 
      context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host); 

    try { 
        SSLContext sslcontext = SSLContext.getInstance("TLS"); 
        sslcontext.init(null, null, null); 
        SSLSocketFactory ssf = sslcontext.getSocketFactory(); 
        Socket socket = ssf.createSocket(); 
        socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), 0); 
        conn.bind(socket); 

        BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest("POST", twitter_endpoint_path); 
        // Including oauth_verifier value to request body 
        request2.setEntity(new StringEntity("oauth_verifier=" + encode(verifier_or_pin), "UTF-8")); 
        request2.addHeader("Authorization", authorization_header_string); 
        httpexecutor.preProcess(request2, httpproc, context); 
        HttpResponse response2 = httpexecutor.execute(request2, conn, context); 
... 
    } 
+0

Bunu yapmak için kodunuzu gösterebilir misiniz? –

+0

@Matthew C güncellendi Soru –

+0

Tam olarak aynı sorunu yaşıyorsanız, bir çözüm buldunuz mu? –

cevap

2

JavaScript kod tabanımızda da aynı durumla karşılaştım. Bir gün uğraştıktan sonra, hatayı çözen bir çözüm buldum. Bu sadece "Content-Type" başlığını "application/x-www-form-urlencoded" değeri ile ekliyor.

Kodum düzgün bir şekilde çalışıyordu, ancak son birkaç aydır çalışmayı durdurdu. Tahminimce Twitter, son zamanlarda içerik türünü açıkça eklemek için bizi zorlayan OAuth işleminin uygulanmasını değiştirdi.

+1

Sanırım belgeye eklerdi, eğer durum buysa –

+1

Eh, HTTP şartnamesinde tanımlandığı için Twitter'ı suçlayamayız. http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1 – Basuke

+1

Elbette, Twitter mühendisleri, içerik türü olmadan isteği kabul ettikleri için kibar olabilirler. Hata mesajı daha açıksa, "İleti isteği ile veriyi işlemek için" Hata: İçerik Türü üstbilgisi gerekiyor "deyin, sorunu daha erken bulabiliriz. – Basuke

İlgili konular