OAuth with Twitter API in C# and .NET

How to use OAuth authorisation when consuming the Twitter API from C#

Note: Since originally writing this article in 2010 things have changed yet again in the Twitter API and Hammock. You may need to revise my example code for this to work. Sorry :)

If you've looked at the Twitter API developer documentation recently then you will probably have noticed a message that appears on the bottom of every page reading:

"August 16, 2010 - The @twitterapi team will be shutting off basic authentication on the Twitter API. All applications, by this date, need to switch to using OAuth."

In other words, if you want your Twitter apps to work after August 16th then you have to use OAuth authentication. But what is OAuth and how do I use it? Well, these are questions I encountered recently when trying to write a simple web-app that used the API to push tweets out when articles were published via a CMS. And, unfortunately, the answers are not that simple or easy to come by…

What is OAuth?

This is the easier of the two questions to answer. In short OAuth, according to the official site, is defined as being:

"An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications."

Sounds good in theory, right? And in many ways it is. But from a developer point of view it takes a lot more work to get it up and running than using simple Basic Authentication (where all you need is a username and password and you are good to go). With OAuth you suddenly find you are dealing with strange things like "consumer keys", "tokens" and even (I kid you not) "nonces". To authenticate you need to pass data back and forth, redirect users to log-in pages, deal with call-back URLs and be able to store values you receive in some kind of permanent storage.

The Twitter documentation for using OAuth hardly makes this much clearer. It's very long, complicated and, frankly, doesn't shed much light on the how you actually put the theory into practice in your favourite language. Luckily, once you've managed to get the required access tokens you can store these and then use them in future requests - it's not something you have to go through for every request, thankfully!

Why Not Use an Existing Twitter Library?

As a C# developer my first thought when I have to consume an API is to see whether someone has already done the hard work. A quick look at the Twitter Libraries page reveals quite a few .NET libraries. Great! So I checked out one of the most popular and widely recommended, called TweetSharp. However, I soon noticed their community letter (now no longer there!) on the front-page of the project in which they state that:

"We no longer subscribe to the "big wrapper" theory for social API consumption. That is, developer platforms on the web are in a constant state of flux, and this is something we should embrace, not resist through hard work. We created Hammock during an evolution in TweetSharp's development in order to address the fact that when APIs change developers should not have to wait for a wrapper to update in order to use it effectively."

This eloquently highlights the problem with using 3rd party open-source libraries that act as wrappers around an API - when the API changes the library can (and will) suddenly break (ironically, since writing this post the entire TweetSharp website has disapeared!). And the Twitter API changes frequently. The fact is, you can't always rely on a library to be kept up to date - often projects start to lag behind the curve or developers get bored and move onto newer pastures. Which leaves you with an angry client wanting to know why something has suddenly stopped working and you, the poor developer, having no idea how to fix it since you haven't changed anything.

This is why I decided to forgo a general Twitter library and, instead, look at the aforementioned Hammock for REST library, which is a much more general purpose library aimed at consuming and wrapping  RESTful services (like the Twitter API). That way if and when the API changes I won't be tied to some closed library but will be able to adapt to the changes myself.

How to Use Hammock for OAuth Authorisation and Authentication

OK, so now I've decided to use Hammock (a .NET library) as a way of abstracting the rather tedious process of making RESTful requests. But how do I get it to perform OAuth authorisation? Sadly the Hammock docs are somewhat lacking, but this is probably why you are reading this, right?

Well, the first thing you need to do is register your Twitter app. This is free and easy and just requires a Twitter account. Once you've done this you will be given two very important pieces of information - a consumer key string and a consumer secret string. Make a note of these as you will need them.

OK, enough of the boring talk, now for some actual C# code example that sends an OAuth request to http://api.twitter.com/oauth/request_token and hopefully gets back a unique OAuth token.

string consumerKey = "ABCD7EM9qNGwQmRBxCcX";
string consumerSecret = "XYZxwwCCkOtdVzWoxcL0lYrmdr1fg6B2atRqbs";
string callBackUrl = "http://localhost/mycallbackurl.aspx";

// Use Hammock to set up our authentication credentials
OAuthCredentials credentials = new OAuthCredentials()
{
    Type = OAuthType.RequestToken,
    SignatureMethod = OAuthSignatureMethod.HmacSha1,
    ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
    ConsumerKey = consumerKey,
    ConsumerSecret = consumerSecret,
    CallbackUrl = callBackUrl
};

// Use Hammock to create a rest client
var client = new RestClient
{
    Authority = "http://twitter.com/oauth",
    Credentials = credentials
};

// Use Hammock to create a request
var request = new RestRequest
{
    Path = "request_token"
};

// Get the response from the request
var response = client.Request(request);

return response;

What we do here is firstly create some OAuth credentials, then pass these to the REST client alongside the base URL for our Request and then we finally make the actual request and get the response back. If everything is OK we should get a 200 OK response and receive an oauth_token and oauth_token_secret back in the response content.

Once we have this we can then use the oauth_token to build up a URL which you will redirect the user to.

http://api.twitter.com/oauth/authorize?oauth_token=YOUR_TOKEN

Twitter will present the user with a page asking them whether they want to grant permission to your app to access their account. This is important. With OAuth it is up to the user of the app to decide whether to grant permission or not. You, the app developer, don't ever need to know their username and password.

After the user (hopefully!) grants permission to our app then Twitter will send back a response to the CallBack URL you specified earlier in the request. You need to have a script "listening" here to receive the GET HTTP response from Twitter. This script needs to capture the oauth_token and oauth_token_secret values returned and store them securely for future usage (perhaps in a database). Once you have these values you can use them in any future requests to the API and they will serve as your authentication from then on (you don't need to get the user to verify their account again, unless they revoke access).

Bring it all Together

To make this convoluted process even simpler I've written my own small C# library that abstracts away the Hammock calls for performing OAuth authorisation. You can download it and example code from the download link at the bottom of this post. It should be quite straightforward to use. In it I define an interface called IOAuthData that is used as a way of defining a standard way of passing data around as well as loading it and saving it to a persistent backing store. It looks like this:

public interface IOAuthData
{
    string ID { get; }
    string ConsumerKey { get; }
    string ConsumerSecret { get; }
    string Token { get; set; }
    string TokenSecret { get; set; }
    int? UserID { get; set; }
    string ScreenName { get; set; }

    bool Load(string id);

    void Save();
}

You can then create concrete classes that implement this interface that, for instance, store the data in a database or wherever you like. In my example project (see download link) I implement a very quick'n'dirty implementation called OAuthXmlData that stores the data in an XML file. It can then be used like this:

// Create a new instance using an XML file as backing
IOAuthData data = new OAuthXmlData();

// Try to load the data from the XML file
if (data.Load(Server.MapPath("~/App_Data/Oauth.xml")))
{
    // Create a new TwitterOauth using consumer key and secret stored in XMl file
    TwitterOAuth oauth = new TwitterOAuth(data.ConsumerKey, data.ConsumerSecret);
    // Specify a call-back URL
    oauth.CallBackUrl = "http://localhost/callbackurl.aspx";
    // Get the authorisation token
    var token = oauth.GetAuthenticationToken();
    // Generate a URL with the token
    Uri authUri = oauth.GetAuthorisationUrl(token);
    // Redirect the user to the Twitter login
    Response.Redirect(authUri.AbsoluteUri);
}
else
{
    throw new ApplicationException("Could not load the OAuth data");
}

In the callbackurl.aspx script receives back the response you can then get the returned tokens like this:

IOAuthData data = new OAuthXmlData();

if (data.Load(Server.MapPath("~/App_Data/Oauth.xml")))
{
    TwitterOAuth oauth = new TwitterOAuth(data.ConsumerKey, data.ConsumerSecret);

    var response = oauth.GetAccessResponse(Page.Request);

    if (response.StatusCode == System.Net.HttpStatusCode.OK)
    {
        // Everything is OK - save the tokens from the response
        oauth.SaveValidatedDataFromResponse(data, response);
    }
    else
    {
        throw new ApplicationException("Not authorised");
    }
}

If the server returns a 200 OK then we can call the Save method on our IOAuthData which will persist it back to the backing store (in this case our XML file). We can then use the values stored here in future requests to the API (without the user needing to grant access again).

Still Confused?

If you are still confused, don't worry, there's a lot to take in. I've included a Visual Studio 2008 project with my library that includes a sample ASP.NET website that has all the code necessary to take the user through authorisation to actually sending tweets via the API. You can grab it from the Download Link just below.

Download Link

Diplo.Twitter VS2008
Posted: 09 August 2010 | Bookmark: Permalink | Comments: Post Comment | Follow: RSS Feed | Bookmark and Share |
Tagged: , , | Topics: Technology_Internet | Social Tags: Twitter, Web 2.0, OAuth, Application programming interface, Representational State Transfer, Cloud standards, Blog hosting services, Online social networking | Industry Terms: web-app | Organisations: Twitter, ASP.NET

18 comments for “OAuth with Twitter”

  • Gravatar of Mike
    Mike

    Hi,

    You mention a project for download... I can't seem to find it on your site.

    Did you / will you upload? It would be sooo useful.

    Cheers

    Mike

     
     
  • Gravatar of Dan Diplo
    Dan Diplo

    Sorry, Mike, some recent updates broke the display of the download link for all blog attachments. But I've fixed it now and the Download link should be obvious (at bottom of post and in left-hand sidebar). Hope you find it of use!

     
     
  • Hello Dan!

    I've been testing your solution, and it works great! But... have you any idea why does it have problems posting utf-8 encoded characters?

    I've tried a lot of encodings/decodings, but still can't get it to work.

    Someting like: "áéíóúüñ" shows like ������ (when you are not logged in Twitter), and with the raw encoding in the Twitter iPhone client.

    Thanks a lot in advance!

     
     
  • Hi Roberto. Character encoding is always a bit of a mystery, but I would have thought UTF-8 would be fine. My UpdateStatus() method, by default, does UrlEncode all posted messages, but maybe this is not enough? I did find this post on Google groups which might be of use to you which mentions this issue. It might be you need to explicitly encode the message string like the author suggests. You might also want to check out oauth-utf8-character-map.

    Good luck and let me know if you come up with a solution.

     
     
  • Hello again Dan!

    I had already tried something like the post on Google Groups that you suggest, but for some reason, the characters appear posted with their UTF-8 encoding! weird...

    Yo can see some examples on a friend's Twitter account that we've been testing: http://twitter.com/mpavezc (log out and see this account)

    I'll keep looking and let you know how this turns out.

    Thank you very much!

     
     
  • Gravatar of Ibrahim
    Ibrahim

    Hi,

    when i click 'start the authorization process on twitter' link on default.aspx page it throws an error saying 'The server responded with a status code of Unauthorized'.

    I have no idea how to resolve this.. Your help will be highly appreciated.

    Thanks in advance

     
     
  • Gravatar of Pradyuman
    Pradyuman

    I am trying to use the twitter api call from windows service. I want one automated functionality to mail the users. So here I am trying to use with "OAuth" type authentication. Here i am passing consumerKey and consumerSecret to get requesttoken using

    function OAuth.GetRequestToken(RequestUrl,consumerKey,consumerSecret) (Her i have Used OAuthLibrary);

    Once i get the requesttoken, i need to Allow the twiiter application for user. so as per my search i need to openup the AuthorizationURL(http://twitter.com/oauth/authorize?oauth_token={0}) and then user need to allow the application access each time service runs to get the PIN number. As i want this functionality to be automated from windowsservice which will run on the scheduler basis. so there is not always user will be available to allow the twitter application to be run each time. So is there anyway i can allow the twitter application by passing the user credential or any other way i can get authenticated to access the twitter api urls.

    Any help would be appriciated.

    Thanks in advance.

     
     
  • Gravatar of sameer
    sameer

    hey I use your code but i came from twitter it gave me following error

    Access to the path 'D:\Hosting\7838969\html\Tw\Oauth.xml' is denied.

    if you can help me please give me answer

    thanks in advance sameer kulkarni

     
     
  • Gravatar of Clement Gitonga
    Clement Gitonga

    Hello Dan,

    I have adapted your sample into a ASP MVC3 App and I can authenticate and save the token details in a DB fine. Problem is when I try to send a tweet I get an error "Could not authenticate with OAuth" I've followed everything step by step but can't seem to find where the error is

    However when I use your app with my credentials I'm able to post.

    what could be the problem?

    CredentialsAreValid function returns ok

     
     
  • The TwitSharp library seems perfect but apparently they (like your solution) rely on Hammock.

    The hammock site is no longer there and a search for Hammock in CodePlex also returns no results.

    The Hammock has fallen...

     
     
  • Hi

    I use your twit app, and it is insert in xml when a user authorize the app.

    And it save one user in xml and that user always in xml.

    I mean how can i insert each user information which used app. in the xml and end session after some time later.

    Thanks,,

     
     
  • We have change create a session for each user which gave authorize with app.

     
     
  • Gravatar of Rahul Kumar
    Rahul Kumar

    Hello Dan Diplo, I like you article and the code that cool but i want to know how we can search the through this dll and the get the user location.

    Please let me know. How we can do this.

    Thanks, Rahul Kumar

     
     
  • A fully implemented OAuth for Twitter and C# has been developped for this Twitter API

    http://tweetinvi.codeplex.com

    Even though the code is more complicated you can have an overview of OAuth and C#.

     
     
  • Gravatar of Zeeshan Sadiq
    Zeeshan Sadiq

    Please! update it according to twitter Twitter API v1.1, As API v1 Retirement is Complete - Use API v1.1

     
     
  • Gravatar of Rachit
    Rachit

    Do we need to change the values of the Authority , OAuthAuthority , Version in the TwitterConstants.cs to communicate with the new API. If yes what are those values ?

     
     
  • Gravatar of Rachit
    Rachit

    Do we need to change the values of the Authority , OAuthAuthority , Version in the TwitterConstants.cs to communicate with the new API. If yes what are those values ?

     
     
  • Gravatar of Sumit
    Sumit

    Its working fine for me but twitter api not returning on call back url mention in code. its returning on url mention in twitter app setting. both url are diffrent. how to return on url mention in code ?

     
     

Post a Comment

Please fill the form in below if you wish to add a comment:
Gravatar

Please don't post raw HTML - use editor above - otherwise you will get an error.