Reputation: 2773
I'm trying to follow this example to access Twitter Stream API (userstream), so I need to do some modifications and this is my final code:
'We need to define some details about the request. This includes a unique oauth_nonce parameter which must be generated per request, and a timestamp
Dim oauth_version As String = "1.0"
Dim oauth_signature_method As String = "HMAC-SHA1"
Dim oauth_nonce As String = Convert.ToBase64String(New ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()))
Dim TimeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
Dim oauth_timestamp As Integer = Convert.ToInt64(TimeSpan.TotalSeconds).ToString()
'The next step is to generate an encrypted oAuth signature which Twitter will use to validate the request.
'To do this, all of the request data is concatenated into a particular format as follows
Dim baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" & _
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}"
Dim baseString As String = String.Format(baseFormat, _
oauth_consumer_key, _
oauth_nonce, _
oauth_signature_method, _
oauth_timestamp, _
oauth_token, _
oauth_version)
'baseString = String.Concat("GET&", Uri.EscapeDataString(stream_url), "&", Uri.EscapeDataString(baseString))
'baseString = String.Concat(Uri.EscapeDataString(stream_url), "&", Uri.EscapeDataString(baseString))
baseString = Uri.EscapeDataString(stream_url)
'Using this base string, we then encrypt the data using a composite of the secret keys and the HMAC-SHA1 algorithm.
Dim compositeKey As String = String.Concat(Uri.EscapeDataString(oauth_consumer_secret), "&", Uri.EscapeDataString(oauth_token_secret))
Dim oauth_signature As String
Dim hasher As HMACSHA1 = New HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))
Using hasher
oauth_signature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)))
End Using
'The oAuth signature is then used to generate the Authentication header.
'This requires concatenating the public keys and the token generated above into the following format
Dim headerFormat As String = "OAuth oauth_nonce=""{0}"", oauth_signature_method=""{1}"", " & _
"oauth_timestamp=""{2}"", oauth_consumer_key=""{3}"", " & _
"oauth_token=""{4}"", oauth_signature=""{5}"", " & _
"oauth_version=""{6}"""
Dim authHeader As String = String.Format(headerFormat, _
Uri.EscapeDataString(oauth_nonce), _
Uri.EscapeDataString(oauth_signature_method), _
Uri.EscapeDataString(oauth_timestamp), _
Uri.EscapeDataString(oauth_consumer_key), _
Uri.EscapeDataString(oauth_token), _
Uri.EscapeDataString(oauth_signature), _
Uri.EscapeDataString(oauth_version))
'We are now ready to send the request, which is the easy part.
'Note, we must also disable the Expect: 100-Continue header using the ServicePointManager.
'Without this code, .NET sends the header by default, which is not supported by Twitter
Dim req As WebRequest
Dim res As HttpWebResponse
Dim streamReader As StreamReader
Dim wait As Integer = 250
Dim jsonRes As String = ""
Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
ServicePointManager.Expect100Continue = False
req = WebRequest.Create(stream_url)
req.Headers.Add("Authorization", authHeader)
res = DirectCast(req.GetResponse(), HttpWebResponse)
streamReader = New StreamReader(res.GetResponseStream(), encode)
While True
jsonRes = streamReader.ReadLine()
'Success
wait = 250
End While
'Abort is needed or responseStream.Close() will hang
req.Abort()
streamReader.Close()
streamReader = Nothing
res.Close()
res = Nothing
In this line: res = DirectCast(req.GetResponse(), HttpWebResponse) I get a 401 - Unauthorized, I guess the problem might be in the line where I prepare the OAuth signature, the original used POST and I will need GET, so I changed it and tried these 3 alternatives:
'baseString = String.Concat("GET&", Uri.EscapeDataString(stream_url), "&", Uri.EscapeDataString(baseString))
'baseString = String.Concat(Uri.EscapeDataString(stream_url), "&", Uri.EscapeDataString(baseString))
baseString = Uri.EscapeDataString(stream_url)
Can you help me getting Twitter OAuth working in VB.NET?
For the moment, Twitterizer is not an option as it only works with Visual Studio 2010, and TwitterVB2.dll only works with REST API, not streaming API, I don't know if there are other third party libraries but at this point I would prefer to solve in my own code (too many unmaintaned and incomplete libraries out there).
Thank you
Upvotes: 2
Views: 7143
Reputation: 2773
Solved, actually the signature was generating ok so the error was somewhere in the method procesing the request, here is my final code, as I mentioned it is based in this C# one:
Dim resource_url As String
resource_url = "https://userstream.twitter.com/2/user.json"
'==========================
'OBTENCION DEL TOKEN Y SIGNATURE OAUTH
Dim oauth_version As String = "1.0"
Dim oauth_signature_method As String = "HMAC-SHA1"
Dim oauth_nonce As String = Convert.ToBase64String(New ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()))
Dim timeSpan As TimeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
Dim oauth_timestamp As String = Convert.ToInt64(timeSpan.TotalSeconds).ToString()
Dim oauth_signature As String = GeneraOAuthSignature(resource_url, _
oauth_nonce, _
oauth_signature_method, _
oauth_timestamp, _
oauth_version)
'==========================
'FORMATEO DEL ENCABEZADO OAUTH
Dim headerFormat As String = "OAuth oauth_nonce=""{0}"", oauth_signature_method=""{1}"", oauth_timestamp=""{2}"", oauth_consumer_key=""{3}"", oauth_token=""{4}"", oauth_signature=""{5}"", oauth_version=""{6}"""
Dim authHeader As String = String.Format(headerFormat, Uri.EscapeDataString(oauth_nonce), Uri.EscapeDataString(oauth_signature_method), Uri.EscapeDataString(oauth_timestamp), Uri.EscapeDataString(oauth_consumer_key), _
Uri.EscapeDataString(oauth_token), Uri.EscapeDataString(oauth_signature), Uri.EscapeDataString(oauth_version))
'==========================
'LLAMADA HTTP
ServicePointManager.Expect100Continue = False
Dim req As WebRequest
Dim res As HttpWebResponse
Dim streamReader As StreamReader
Dim contenidoRespuesta As String = ""
Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
req = WebRequest.Create(resource_url)
req.Timeout = -1
req.Headers.Add("Authorization", authHeader)
res = DirectCast(req.GetResponse(), HttpWebResponse)
'==========================
'PROCESAR RESPUESTA
streamReader = New StreamReader(res.GetResponseStream(), encode)
While True
contenidoRespuesta = streamReader.ReadLine()
End While
'==========================
'CIERRE DE STREAMS Y COMUNICACIONES
'Abort is needed or streamReader.Close() will hang
req.Abort()
streamReader.Close()
streamReader = Nothing
res.Close()
res = Nothing
Where:
Function GeneraOAuthSignature(ByVal stream_url As String, _
ByVal oauth_nonce As String, _
ByVal oauth_signature_method As String, _
ByVal oauth_timestamp As String, _
ByVal oauth_version As String) As String
'The next step is to generate an encrypted oAuth signature which Twitter will use to validate the request.
'To do this, all of the request data is concatenated into a particular format as follows
Dim baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" & _
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}"
Dim baseString As String = String.Format(baseFormat, _
oauth_consumer_key, _
oauth_nonce, _
oauth_signature_method, _
oauth_timestamp, _
oauth_token, _
oauth_version)
baseString = String.Concat("GET&", Uri.EscapeDataString(stream_url), "&", Uri.EscapeDataString(baseString))
'Using this base string, we then encrypt the data using a composite of the secret keys and the HMAC-SHA1 algorithm.
Dim compositeKey As String = String.Concat(Uri.EscapeDataString(oauth_consumer_secret), "&", Uri.EscapeDataString(oauth_token_secret))
Dim oauth_signature As String
Dim hasher As HMACSHA1 = New HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))
Using hasher
oauth_signature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)))
End Using
Return oauth_signature
End Function
Upvotes: 3