Sign in with Twitter in MVC3
For the last few days I have been working with MVC3 making a site that relies upon Twitter as the basis for user accounts, so I implemented Sign in with Twitter. It turned out to be incredibly easy.
First of all, you’ll need a controller to handle your sign on button and the OAuth callback. I named mine /Controllers/AccountController.cs. Only one method is required, it will handle the /Account/Logon/ route.
The first time the user hits the controller (they aren’t logged in) the OAuth arguments will be null, but there will be a ReturnUrl. The app reaches out to Twitter and gets a request token, then redirects the user to the authentication url. Once they have authenticated (and authorized your application) at Twitter, they will be sent back to the same /Account/Logon/ address, but this time with the OAuth arguments. The controller will then go to Twitter and get an access token. My application maintains user accounts, so I lookup the user account and create it if it doesn’t exist. I’m then using the built in FormsAuthentication class to set their authentication cookie. From then on, ASP.NET recognizes them as an authenticated user and all the built in goodies just work.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | // GET: Account/Logon/ public ActionResult Logon(string oauth_token, string oauth_verifier, string ReturnUrl) { if (string.IsNullOrEmpty(oauth_token) || string.IsNullOrEmpty(oauth_verifier)) { UriBuilder builder = new UriBuilder(this.Request.Url); builder.Query = string.Concat( builder.Query, string.IsNullOrEmpty(builder.Query) ? string.Empty : "&", "ReturnUrl=", ReturnUrl); string token = OAuthUtility.GetRequestToken( ConfigurationManager.AppSettings["TwitterConsumerKey"], ConfigurationManager.AppSettings["TwitterConsumerSecret"], builder.ToString()).Token; return Redirect(OAuthUtility.BuildAuthorizationUri(token, true).ToString()); } var tokens = OAuthUtility.GetAccessToken( ConfigurationManager.AppSettings["TwitterConsumerKey"], ConfigurationManager.AppSettings["TwitterConsumerSecret"], oauth_token, oauth_verifier); using (TwitterizerDbContext db = new TwitterizerDbContext()) { var user = db.Users.Find(tokens.UserId); if (user == null) { user = new User() { TwitterUserId = tokens.UserId, ScreenName = tokens.ScreenName, TwitterAccessKey = tokens.Token, TwitterAccessSecret = tokens.TokenSecret }; db.Users.Add(user); db.SaveChanges(); } FormsAuthentication.SetAuthCookie(user.ScreenName, false); } if (string.IsNullOrEmpty(ReturnUrl)) return Redirect("/"); else return Redirect(ReturnUrl); } |
For the UI, I used a partial view, very similar to the view that Visual Studio creates as part of the project template. I named this file /Views/Shared/_LogOnPartial.cshtml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @using Twitterizer.PublicWeb
<div class="logon-form">
@if (User.Identity.IsAuthenticated)
{
<strong>
Logged in as @User.Identity.Name
|
@Html.ActionLink("Edit", "Edit", "Account")
|
@Html.ActionLink("Log out", "Logout", "Account")
</strong>
}
else
{
@Html.ActionImage("Logon", "Account", null, "~/Content/images/sign-in-with-twitter-l.png", "Sign in with twitter")
}
</div> |
I can then place the partial view on any other view with a simple command:
1 | @Html.Partial("_LogOnPartial") |
One of the huge benefits of this is that the user will be automatically logged into the site the moment they try to access a protected resource, provided that they are logged into Twitter and have already authorized my application. The round trip to/from Twitter is seamless and the user may not even notice that it happened.
Update: I forgot to mention 2 things: the image I’m using for the sign on button can be downloaded here and I have a special ActionImage extension method you’ll need to use my example. Just place this method in a static class in your project:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static MvcHtmlString ActionImage(this HtmlHelper html, string action, string controller, object routeValues, string imagePath, string alt) { var url = new UrlHelper(html.ViewContext.RequestContext); // build the <img> tag var imgBuilder = new TagBuilder("img"); imgBuilder.MergeAttribute("src", url.Content(imagePath)); imgBuilder.MergeAttribute("alt", alt); string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing); // build the <a> tag var anchorBuilder = new TagBuilder("a"); anchorBuilder.MergeAttribute("href", url.Action(action, controller, routeValues)); anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal); return MvcHtmlString.Create(anchorHtml); } |
7 Responses to Sign in with Twitter in MVC3
Leave a Reply Cancel reply
Resources
Other Libraries
Other Projects







Works like a charm! Thanks for the library. I’ll be using it extensively.
Wow…this is very important for developers!!!!
Great work!!!!!!!!!!
TwitterizerDbContext doesn’t exist as well as the User class with TwitterUserId property…
I’m using Twittterizer2 assembly, version 2.4.0.26532 – any ideas?
Take care,
Palo
The TwitterDbContext and User class are part of my application’s data tier (using the Entity Framework). You will need to replace those with your own database logic.
It’s working now – thank you!
Just a note for other starters like me: Twitter doesn’t allow localhost in the callback URL (you’ll be getting 401 from GetRequestToken method).Instead, you can use the loopback address 127.0.0.1. FMI – https://dev.twitter.com/discussions/1066
I like social networking
Very cool. Also, just an FYI, but MVC 4 will come with OAuth and Open ID out of the box in its templates (same for Web Pages and Web Forms) so hopefully you won’t even have to do most of that to get it working. I’ll be curious to see how customization goes for you in the new stuff though and if it’s hard or easy.
-Erik