I'm writing to write a C# method to generate a authentication header for Twitter. I'm trying to search twitter through this API: https://api.twitter.com/1.1/search/tweets.json.
Here's the URL I call:
https://api.twitter.com/1.1/search/tweets.json?q=%23countryman+OR+%23johncooperworks+OR+%40mini%26since_id%3d24012619984051000%26max_id%3d250126199840518145%26result_type%3dmixed%26count%3d4
Here's my method:
private string GetTwitterAuthHeader()
{
const string oauthConsumerKey = "";
const string oauthConsumerSecret = "";
const string oauthToken = "";
const string oauthTokenSecret = "";
const string oauthVersion = "1.0";
const string oauthSignatureMethod = "HMAC-SHA1";
var oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture)));
var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var oauthTimestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture);
const string resourceUrl = "https://api.twitter.com/1.1/search/tweets.json";
const string baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}";
var baseString = string.Format(baseFormat,
oauthConsumerKey,
oauthNonce,
oauthSignatureMethod,
oauthTimestamp,
oauthToken,
oauthVersion
);
baseString = string.Concat("GET&", Uri.EscapeDataString(resourceUrl), "&", Uri.EscapeDataString(baseString));
var compositeKey = string.Concat(Uri.EscapeDataString(oauthConsumerSecret),
"&", Uri.EscapeDataString(oauthTokenSecret));
string oauthSignature;
using (var hasher = new HMACSHA1(Encoding.ASCII.GetBytes(compositeKey)))
{
oauthSignature = Convert.ToBase64String(
hasher.ComputeHash(Encoding.ASCII.GetBytes(baseString)));
}
const string headerFormat = "OAuth oauth_consumer_key=\"{0}\", " +
"oauth_nonce=\"{1}\", " +
"oauth_signature=\"{2}\", " +
"oauth_signature_method=\"{3}\", " +
"oauth_timestamp=\"{4}\", " +
"oauth_token=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oauthConsumerKey),
Uri.EscapeDataString(oauthNonce),
Uri.EscapeDataString(oauthSignature),
Uri.EscapeDataString(oauthSignatureMethod),
Uri.EscapeDataString(oauthTimestamp),
Uri.EscapeDataString(oauthToken),
Uri.EscapeDataString(oauthVersion)
);
return authHeader;
}
The error I get is:
{
"errors": [
{
"message": "Bad Authentication data",
"code": 215
}
]
}
Any pointers?
Do I need to account for the actual search query in generating the auth header? (e.g. the values I append to the search API)?
I'm finding it hard to debug.
Thanks!
EDIT:
Based on feedback, here's an update:
var resourceUrl = "https://api.twitter.com/1.1/search/tweets.json";
const string baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&q={6}";
var baseString = string.Format(baseFormat,
oauthConsumerKey,
oauthNonce,
oauthSignatureMethod,
oauthTimestamp,
oauthToken,
oauthVersion,
query
);
baseString = string.Concat("GET&",
Uri.EscapeDataString(resourceUrl), "&",
Uri.EscapeDataString(baseString));
Having read https://dev.twitter.com/oauth/overview/creating-signatures closer, this seems to be right. Still, I get the same error.