views:

77

answers:

1

So I am building a java script that is used in conjunction of my C++ application for sending direct messages to users. the script does the work of building the request that i send. When i send a request i receive "Incorrect signature" or "can not authenticate you" Does anyone see something i am missing or am doing wrong? I am continuing to investigate. Thank you in advance

Javascript:

var nDate = new Date();
var epoch = nDate.getTime();
var nounce = "";

nounce = Base64.encode(epoch+randomString()); 

var Parameters =   [
   "oauth_consumerkey="+sConsumerKey,
   "oauth_nonce="+nounce,
   "oauth_signature_method=HMAC-SHA1",
   "oauth_timestamp="+epoch,
   "oauth_token="+sAccessToken,
   "oauth_version=1.0",
   "text="+sText,
   "user="+sUser];

var SortedParameters = Parameters.sort(); 
var joinParameters = SortedParameters.join("&");
var encodeParameters = escape(joinParameters);



signature_base_string = escape("POST&"+NormalizedURL+"&"+encodeParameters);

signature_key = sConsumerSecret+"&"+sAccessSecret;

signature = Base64.encode(hmacsha1(signature_base_string,signature_key));


sAuthHeader = "
  OAuth realm=, 
  oauth_nonce="+nounce+",
  oauth_timestamp="+epoch+",     
  oauth_consumer_key="+sConsumerKey+",
  oauth_signature_method=HMAC-SHA1, 
  oauth_version=1.0,
  oauth_signature="+signature+",
  oauth_token="+sAccessToken+",
  text="+sText;

goNVOut.Set("Header.Authorization: ", sAuthHeader);
+1  A: 

Here are a couple things to be careful about:

  • JavaScript's "escape" function will not work for OAuth URL encoding, as per the OAuth Spec.

5.1. Parameter Encoding

All parameter names and values are escaped using the [RFC3986] percent-encoding (%xx) mechanism. Characters not in the unreserved character set ([RFC3986] section 2.3) MUST be encoded. Characters in the unreserved character set MUST NOT be encoded. Hexadecimal characters in encodings MUST be upper case. Text names and values MUST be encoded as UTF-8 octets before percent-encoding them per [RFC3629].

        unreserved = ALPHA, DIGIT, '-', '.', '_', '~'

JavaScript's escape function will let @ * + / through, unescaped. I'm confident that that will break the signature signing process, since the server will be escaping those, and the HMAC-SHA1 value it computes will be different than yours.

  • Be sure to URL encode your base URI, NormalizedURL, as well.

I found that getting the encoding correct is the most tedious part of OAuth. Be sure to use upper-case letters in your new "url_encode" function.

Here's my C++ code to do the URL encoding. It could be optimized a bit but should be easy to understand.

char hexdigit(int ch)
{
    assert(ch < 16);
    assert(ch >= 0);
    if (ch >= 10)
        return 'A' + ch - 10;
    return '0' + ch;
}

std::string url_encode(const std::string &to_encode)
{
    std::stringstream ss;
    for (std::string::const_iterator ich = to_encode.begin();
         ich != to_encode.end();
         ich++)
    {
        unsigned char ch = (unsigned char)*ich;
        if (isalpha(ch) || isdigit(ch) || ch == '-' || ch == '_' || ch == '.' || ch == '~')
        {
            ss << ch;
        }
        else
        {
            ss << '%';
            ss << hexdigit(ch >> 4);
            ss << hexdigit(ch & 0xf);
        }
    }

    std::string encoded = ss.str();
    return encoded;
}

Best of luck!

Will Bradley
Robot Wheelie LLC

Will Bradley
Thanks Will, the encoding was getting me into trouble as well. now i am just slowly debugging until the format is what needs to be for Twitter. Thanks you guys!!!
Darxval