Returning 401 for access_token from desktop app


#1

I am a developer that is new to the Twitter API but have years of experience with REST calls. I have been attempting to add a feature to my C# desktop appllication that posts status updates for a user. I have been working thru the authentication process and have successfully issued the request_token, built the application approval URL, Used the URL in a browser to approve the application and get a PIN. However I have been unable to successfully issue the access_token, each attempt returns a 401. I have included an abstract of my processing flow and was hoping someone could point out what is wrong with my final REST request.

        //Build the signature string
        StringBuilder curBaseString = new StringBuilder( "" );
        curBaseString.Append( "POST&" + Uri.EscapeDataString( "https://api.twitter.com/oauth/request_token" ) + "&" );
        curBaseString.Append( Uri.EscapeDataString( "oauth_callback=oob" ));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_consumer_key=MyConsumerKey" ));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_nonce=1D5A4D8A"));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_signature_method=HMAC-SHA1" ));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_timestamp=1365274825" ));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_version=1.0" ));

        HMACSHA1 curHasher = new HMACSHA1( new ASCIIEncoding().GetBytes( Uri.EscapeDataString( "MyConsumerSecret" ) + "&" + Uri.EscapeDataString( "" ) ) );
        String curSignature = Convert.ToBase64String( curHasher.ComputeHash( new ASCIIEncoding().GetBytes( curBaseString.ToString() ) ) );

        StringBuilder curAuthHeaderParm = new StringBuilder( "" );
        curAuthHeaderParm.Append( "OAuth oauth_callback=\"oob\"" );
        curAuthHeaderParm.Append( ", oauth_consumer_key=\"" + Uri.EscapeDataString( "MyConsumerKey" ) + "\"" );
        curAuthHeaderParm.Append( ", oauth_nonce=\"" + Uri.EscapeDataString( "1D5A4D8A") + "\"" );
        curAuthHeaderParm.Append( ", oauth_signature_method=\"" + Uri.EscapeDataString("HMAC-SHA1") + "\"" );
        curAuthHeaderParm.Append( ", oauth_signature=\"" + Uri.EscapeDataString( curSignature ) + "\"" );
        curAuthHeaderParm.Append( ", oauth_timestamp=\"" + Uri.EscapeDataString( "1365274825" ) + "\"" );
        curAuthHeaderParm.Append( ", oauth_version=\"" + "1.0" + "\"" );

        String curPostMessage = "";
        RequestTokenResponse = curSendMessage.sendMessage( "https://api.twitter.com/oauth/request_token", curAuthHeaderParm.ToString(), "application/x-www-form-urlencoded;charset=UTF-8", curPostMessage );
        MessageBox.Show("https://api.twitter.com/oauth/authorize?oauth_token=" + Value of "oauth_token" in RequestTokenResponse);

        //Build the signature string
        StringBuilder curBaseString = new StringBuilder( "" );
        curBaseString.Append( "POST&" + Uri.EscapeDataString( "https://api.twitter.com/oauth/access_token" ) + "&" );
        curBaseString.Append( Uri.EscapeDataString( "&oauth_consumer_key=MyConsumerKey" ));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_nonce=1D5A4D8A"));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_signature_method=HMAC-SHA1" ));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_timestamp=1365274825" ));
        curBaseString.Append( Uri.EscapeDataString( "&oauth_token=" + Value of "oauth_token" in RequestTokenResponse ) );
        curBaseString.Append( Uri.EscapeDataString( "&oauth_version=1.0" ));

        HMACSHA1 curHasher = new HMACSHA1( new ASCIIEncoding().GetBytes( Uri.EscapeDataString( "MyConsumerSecret" ) 
        	+ "&" + Uri.EscapeDataString( "Value of "oauth_token_secret" in RequestTokenResponse " ) ) );
        String curSignature = Convert.ToBase64String( curHasher.ComputeHash( new ASCIIEncoding().GetBytes( curBaseString.ToString() ) ) );

        StringBuilder curAuthHeaderParm = new StringBuilder( "" );
        curAuthHeaderParm.Append( "OAuth );
        curAuthHeaderParm.Append( "oauth_consumer_key=\"" + Uri.EscapeDataString( "MyConsumerKey" ) + "\"" );
        curAuthHeaderParm.Append( ", oauth_nonce=\"" + Uri.EscapeDataString( "1D5A4D8A" ) + "\"" );
        curAuthHeaderParm.Append( ", oauth_signature_method=\"" + Uri.EscapeDataString("HMAC-SHA1") + "\"" );
        curAuthHeaderParm.Append( ", oauth_signature=\"" + Uri.EscapeDataString( curSignature ) + "\"" );
        curAuthHeaderParm.Append( ", oauth_timestamp=\"" + Uri.EscapeDataString( "1365274825" ) + "\"" );
        curAuthHeaderParm.Append( ", oauth_token=\"" + Uri.EscapeDataString(Value of "oauth_token" in RequestTokenResponse) + "\"" ) );
        curAuthHeaderParm.Append( ", oauth_version=\"" + "1.0" + "\"" );

        String curPostMessage = "";
        curSendMessage.sendMessage( "https://api.twitter.com/oauth/access_token", curAuthHeaderParm.ToString(), "application/x-www-form-urlencoded;charset=UTF-8", curPostMessage );

#2

It looks like you may not be including your oauth_verifier on the oauth/access_token request. Since you’re doing OOB-mode OAuth 1.0A, it’s the “PIN code” displayed on the screen after approving access. Include that as oauth_verifier on oauth/access_token and you’ll likely be in good shape.


#3

Thank you. That did it. I needed to include the oauth_verifier in the String Base, header, and post message. Once I did that I was able to get a successful request. Thank you. I’ve been looking at that and tweaking that for days.