Hi Allister,
I've had a bit of time to do some reading on OAuth authentication with Twitter, and I'm sharing below what I've found out so far...
It appears there are two ways of authenticating with the Twitter API using OAuth - either using Application authentication or User authentication:
- Application authentication would allow you to hard code the authentication details in a server-side app and your server app would make requests to Twitter on behalf of the app, without the context of a specific user, and then you could render the returned data as JSON to the client side if needed.
- User authentication would still require the server-side app to make requests to Twitter on your behalf, but you would be redirected to Twitter as part of the process to authenticate yourself and grant the app permission to use your Twitter User context to make requests using your Twitter account.
If you just wanted to return some basic JSON data from Twitter (such as a particular user's timeline, or Tweets that match a particular search query) then Application authentication should suffice. You would however need to use User authentication if you wanted to post a Tweet on behalf of a user.
Due to Twitter disabling the v1.0 API, and now requiring OAuth authentication to use the API, you would need to have a web service in place on your server, and this web service would act as a proxy between your front-end Sencha app and the Twitter API service. This web service would also contain your tokens/keys (you wouldn't want that info kept in JavaScript files as it's private stuff).
The example below shows how you can implement Application authentication in a .NET web app. This small .NET app contains one page that will make requests to Twitter and pass back the JSON response, so Twitter data can be shown in a Sencha-based app.
I'm in no way an expert on OAuth authentication - this is just something I've tested, and it works, so I'm sharing for others that are interested! Most of the code below is based on an example I found here: http://www.codeproject.com/Articles/...tion-using-Net, and I've tweaked this to do a GET request instead of a POST request. The same example could be ported to other languages and I've included details of the HTTP requests made by .NET to give you an idea of the format of the requests being sent, so this should be easily portable to other server-side languages like PHP etc.
First, you need to create a new application on the Twitter Developers site (https://dev.twitter.com/apps), followed by creating an Access Token. This will create some tokens and keys that you'll need for authenticating the .NET app with Twitter so it can issue requests to the Twitter API.
Then, create a new .NET web app inside of Visual Studio (I'm using the free version of Visual Studio Express 2012 for Web). In the example below I'm using a Generic Handler file (called "TwitterFeed.ashx") that will contain the following code. As the keys and token values are supposed to be kept secret/private I have replaced them with sample values:
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace OAuthFormDemo
{
/// <summary>
/// Makes GET requests to the Twitter API using Application Authentication
/// </summary>
public class TwitterFeed : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// Based in part on the following example: http://www.codeproject.com/Articles/247336/Twitter-OAuth-authentication-using-Net
// Tweaked to illustrate a GET request (instead of POST).
// Demonstrates application authentication with an existing Application oAuth Token (via Twitter Developer Portal).
string oAuthAccessToken = "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw";
string oAuthAccessTokenSecret = "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA";
string oAuthConsumerKey = "GDdmIQH6jhtmLUypg82g";
string oAuthConsumerSecret = "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98";
string oAuthVersion = "1.0";
string oAuthSignatureMethod = "HMAC-SHA1";
string oAuthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
string oAuthTimeStamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
string resourceUrl = "https://api.twitter.com/1.1/statuses/user_timeline.json";
string screenName = "sencha";
string baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}";
string baseString = string.Format(baseFormat,
oAuthConsumerKey,
oAuthNonce,
oAuthSignatureMethod,
oAuthTimeStamp,
oAuthAccessToken,
oAuthVersion,
screenName
);
baseString = string.Concat("GET&", Uri.EscapeDataString(resourceUrl),
"&", Uri.EscapeDataString(baseString));
string compositeKey = string.Concat(Uri.EscapeDataString(oAuthConsumerSecret),
"&", Uri.EscapeDataString(oAuthAccessTokenSecret));
string oAuthSignature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
oAuthSignature = Convert.ToBase64String(
hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
"oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
"oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oAuthNonce),
Uri.EscapeDataString(oAuthSignatureMethod),
Uri.EscapeDataString(oAuthTimeStamp),
Uri.EscapeDataString(oAuthConsumerKey),
Uri.EscapeDataString(oAuthAccessToken),
Uri.EscapeDataString(oAuthSignature),
Uri.EscapeDataString(oAuthVersion)
);
ServicePointManager.Expect100Continue = false;
// Append query string parameters to the URL
resourceUrl += "?screen_name=" + screenName;
// Create a new HTTP request, and append the Authorization header
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resourceUrl);
request.Headers.Add("Authorization", authHeader);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
// Get the response and read the JSON response data
WebResponse response = request.GetResponse();
string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
// Render the JSON response out to the page
context.Response.ContentType = "application/json";
context.Response.Write(responseData);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
The code above will retrieve data from a user's timeline, and I've specified a "screen_name" of "Sencha", so it's basically going to retrieve recent Tweets from the Sencha timeline.
When we launch "TwitterFeed.ashx" in the browser, I can use a proxy tool (such as Fiddler - http://fiddler2.com/get-fiddler) to analyse the encrypted HTTP requests being sent to Twitter. This is the raw request sent from the .NET app to Twitter (again, I have replaced the secret key and token values in the request header with samples):
Code:
GET https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=sencha HTTP/1.1
Authorization: OAuth oauth_nonce="NjM1MDcyNTA1MzE5MDE2NjM4", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1371650132", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_token="819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw", oauth_signature="5wt8g%2FiKP9BG2XL%2BwdszM35irhs%3D", oauth_version="1.0"
Content-Type: application/x-www-form-urlencoded
Host: api.twitter.com
Connection: Keep-Alive
We can see the GET request above, along with the Authorization header and various OAuth parameters. The raw response that comes back is as follows (I've concatenated the JSON data at the end of the response due to its long length):
Code:
HTTP/1.1 200 OK
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
content-length: 82320
content-type: application/json;charset=utf-8
date: Wed, 19 Jun 2013 13:55:32 GMT
expires: Tue, 31 Mar 1981 05:00:00 GMT
last-modified: Wed, 19 Jun 2013 13:55:32 GMT
pragma: no-cache
server: tfe
set-cookie: lang=en
set-cookie: guest_id=v1%3A137165013211436301; Domain=.twitter.com; Path=/; Expires=Fri, 19-Jun-2015 13:55:32 UTC
status: 200 OK
strict-transport-security: max-age=631138519
x-access-level: read
x-frame-options: SAMEORIGIN
x-rate-limit-limit: 180
x-rate-limit-remaining: 179
x-rate-limit-reset: 1371651032
x-transaction: b9a4f32d0a9698cc
x-xss-protection: 1; mode=block
[{"created_at":"Wed Jun 19 00:15:41 +0000 2013","id":347145623784529921,"id_str":"347145623784529921","text":...
Because I'm doing "Response.Write" in the .NET file above, the JSON response from Twitter is being rendered to the page. This can then be linked to a Sencha application for showing Twitter timeline data.
You will probably find there are various helper libraries out there that will assist in OAuth authentication, but hopefully the detailed example above illustrates how this works at a low level. Certainly, for .NET there's Twitterizer (https://github.com/Twitterizer/Twitterizer), a .NET class library that provides simple APIs to authenticate and retrieve data from Twitter. But as long as you are able to fire off HTTP requests like the above from your own server app with the Authorization header set, there should be no reason why you can't do the same.
Here's a screenshot of how the above example looks in practice:
OAuthTwitter.jpg
When I get some more spare time, I'll see if I can get an example working that shows how to do User authentication.
Hope this helps!