February 29, 2012

Getting started with OAuth Providers

I recently started working on a project where we want to allow users to log in using OAuth providers such as Google, Facebook and Twitter.

There are a number of libraries around that do most of the hard work communicating with OAuth providers (we’re using DotNetOpenAuth). What I couldn’t find however was a comprehensive resource on how to register, test and retrieve profile information from each provider.

Since I’ve now completed consumers for Google, Facebook, Twitter, LinkedIn and Windows Live I thought I would share that information here.

Getting Started - Setting up a test domain

With the exception of Google, all of the above providers require that you use a fully qualified domain name when registering your application. The OAuth 1.0a providers (Twitter and LinkedIn) can be tested on localhost but you need to provide a valid domain for the callback url (twitter) / Javascript API Domain (LinkedIn).

The Windows Live requires a valid unique domain.

Therefore the easiest solution is to choose a unique/random domain that can be added to your hosts file and used to test your application locally.

Run a command prompt as administrator and execute the following:

notepad c:\windows\system32\drivers\etc\hosts

This will open up the Windows Hosts file. Add an entry for your chosen domain:

127.0.0.1 myrandomdomain1234.com

Save the file. You can verify that the domain resolves to your computer by pinging it from the command prompt:

C:\Windows\System32\drivers\etc>ping myrandomdomain1234.com

Pinging myrandomdomain1234.com [127.0.0.1] with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Now we need to configure IIS/IISExpress to map this domain to your web application.

IIS (7.0) upwards

Open up IIS Manager (Start > Run > Inetmgr.exe), locate your web application under the Sites list and select “Bindings” from the action menu on the right. Add a binding for your chosen hostname (e.g. myrandomdomain1234.com).

IIS Express

If you’re using IIS Express (which is likely if you are developing with Visual Studio) you need to add the binding via the applicationhost.config file.

Close Visual Studio if it’s already open.

Open up “[Your documents directory]\IISExpress\config\applicationhost.config” in the editor of your choice and do a search for your applications name.

Under the bindings section add a binding for your test domain:

<site name="Sample" id="6">
    <application path="/" applicationPool="Clr4IntegratedAppPool">
        <virtualDirectory path="/" physicalPath="D:\Projects\Sample" />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:52770:localhost" />
		<binding protocol="http" bindingInformation="*:52770:myrandomdomain1234.com" />
    </bindings>
</site>

Save the file then run your web application. You should be able to browse to it using your test domain (don’t forget the port):

Running your application under the test domain

Great, we’re ready to start working with the OAuth providers.

Profile information

In most cases you’ll want some basic profile information from the OAuth provider. In the examples below I’ll assume you require the following data:

  • User Id (unique to the OAuth provider)
  • Name
  • Email

Not all of this information is provided in the original request token response so an additional API call is usually required.

Google

OAuth Version: 2.0
OAuth API Details: http://code.google.com/apis/accounts/docs/OAuth2.html

Registering your application

  • Go to https://code.google.com/apis/console
  • Create a new project
  • After giving your project a name you’ll be asked to select services for a project. You don’t need access to any services just to perform authentication so click the “API Access” link on the menu.
  • Click “Create an OAuth 2.0 client ID”

Create an OAuth 2.0 client

  • Supply a product name and a logo (optional - this will be displayed to the user when they are redirected to the OAuth provider to authorize your application)

Supply a product name and logo

  • Choose “Web Application” as the application type, enter your test domain, then click “Create client ID”. By default this will register a redirect url of {yourdomain}/oauth2callback. You can change the callback address by clicking the “Edit Settings” link on the API Access page. Note: The registered redirect address needs to match that sent by your application.

Application details

  • You’ll then be presented with your “Client ID for web applications”. The “Client ID” and “Client Secret” are necessary to make OAuth requests. You can add additional domains for your application by clicking the “Edit Settings” link.

Viewing API keys

Authorized OAuth Response

{
  "access_token" : "xxxxxxxxx",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "id_token" : "xxxxxxxxxxxxxxxxxx"
}

Getting user profile information

In order to retrieve the required profile information we need to pass the following scopes when sending the access token request:

Example:

GET https://www.googleapis.com/oauth2/v1/userinfo?access_token=YourAuthorizedToken

Response:

{
 "id": "105863839952470494725",
 "email": "email@somedomain.com",
 "verified_email": true,
 "name": "Ben Foster",
 "given_name": "Ben",
 "family_name": "Foster",
 "link": "https://profiles.google.com/105863839952470494725",
 "picture": "https://lh4.googleusercontent.com/-lESfmsqICks/AAAAAAAAAAI/AAAAAAAAABc/q9x2Oq9-ZXQ/photo.jpg",
 "gender": "male"
}

Further Documentation - http://code.google.com/apis/accounts/docs/OAuth2Login.html#userinfocall

Twitter

OAuth Version: 1.0a
OAuth API Details: https://dev.twitter.com/docs/auth/implementing-sign-twitter

Registering your application

  • Go to https://dev.twitter.com/apps/new
  • Fill out the details of your application. The application name must be unique. Since OAuth 1.0a requires that the callback url must be specified in the request, the callback url here can be anything - but you must enter something.

Twitter Application Details

  • You’ll then be provided with your OAuth settings. The “Consumer Key” and “Consumer Secret” are necessary to make OAuth requests.

Twitter API Settings

Authorized OAuth Response

oauth_token=xxxxxxxxoauth_token_secret=xxxxxxx&user_id=12354678&screen_name=benfosterdev

Getting user profile information

As you can see, the above response also includes the Twitter user id and screen name but we still need to make an additional API request to get the users name.

Note: The Twitter API does not allow access to a user’s email address so you will need to handle this within your application.

Example:

GET https://api.twitter.com/1/users/show.json?screen_name=benfosterdev

Response:

{
	is_translator: false,
	id: 154950149,
	favourites_count: 72,
	profile_background_color: "C0DEED",
	lang: "en",
	geo_enabled: false,
	location: "Val Thorens, France",
	profile_background_image_url: "http://a0.twimg.com/images/themes/theme1/bg.png",
	utc_offset: null,
	profile_link_color: "0084B4",
	profile_background_image_url_https: "https://si0.twimg.com/images/themes/theme1/bg.png",
	name: "Ben Foster",
	profile_image_url: "http://a0.twimg.com/profile_images/1585314644/IMG00168-20111012-2117_normal.jpg",
	time_zone: null,
	followers_count: 154,
	default_profile: true,
	protected: false,
	profile_use_background_image: true,
	following: false,
	id_str: "154950149",
	profile_text_color: "333333",
	listed_count: 3,
	description: "Developer from the UK who enjoys doing clever things with the web.",
	contributors_enabled: false,
	profile_sidebar_border_color: "C0DEED",
	follow_request_sent: false,
	friends_count: 149,
	url: "http://ben.onfabrik.com",
	statuses_count: 1897,
	screen_name: "benfosterdev",
	created_at: "Sat Jun 12 17:38:12 +0000 2010",
	profile_background_tile: false,
	show_all_inline_media: false,
	profile_image_url_https: "https://si0.twimg.com/profile_images/1585314644/IMG00168-20111012-2117_normal.jpg",
	profile_sidebar_fill_color: "DDEEF6",
	status: {
		id_str: "174606533940887553",
		retweeted: false,
		retweet_count: 0,
		created_at: "Tue Feb 28 21:26:56 +0000 2012",
		geo: null,
		in_reply_to_status_id_str: "174484369564647424",
		in_reply_to_user_id: 15525039,
		in_reply_to_user_id_str: "15525039",
		in_reply_to_status_id: 174484369564647420,
		favorited: false,
		in_reply_to_screen_name: "dgomesbr",
		truncated: false,
		contributors: null,
		place: null,
		source: "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",
		id: 174606533940887550,
		coordinates: null,
		text: "@dgomesbr if you post the details on StackOverflow and send me a link I'll have a look (or at least someone else may be able to help)"
	},
	notifications: false,
	default_profile_image: false,
	verified: false
}

Further Documentation - https://dev.twitter.com/docs/api/1/get/users/show

LinkedIn

OAuth Version: 1.0a
OAuth API Details: https://developer.linkedin.com/documents/oauth-overview

Registering your application

LinkedIn Application Details

  • You can then click your application name to view your “API Key” and “Secret Key”

LinkedIn API Keys

Authorized OAuth Response

oauth_token=xxxxxxxxoauth_token_secret=xxxxxxx&oauth_expires_in=0&oauth_authorization_expires_in=0

Getting user profile information

The LinkedIn Profile API supports Field Selectors (https://developer.linkedin.com/documents/field-selectors) to limit the information returned from an API call. In this example we’re requesting the Id, First Name and Last Name.

Note: The LinkedIn API does not allow access to a user’s email address so you will need to handle this within your application.

Example:

GET http://api.linkedin.com/v1/people/~:(id,first-name,last-name)?format=json

Response:

{
  "firstName": "Ben",
  "id": "4ZdrJYlSgH",
  "lastName": "Foster"
}

Further Documentation - https://developer.linkedin.com/documents/profile-api

Facebook

OAuth Version: 2.0
OAuth API Details: http://developers.facebook.com/docs/authentication

Registering your application

Facebook Create Application

  • The App Settings page displays your “App ID” and “App Secret”

Facebook API Keys

  • Enter the domain of your web application (e.g. your test domain)

Facebook Application Details

  • Under “Select how your app integrates with Facebook” tick “Website” and enter your domain (facebook will only redirect to urls at this domain)

Facebook Application Details

Authorized OAuth Response

access_token=xxxxxxx&expires=5183997

Getting user profile information

By default the user API does not include the user’s email address. To access this you need to pass the “email” scope when requesting an access token.

Example:

GET https://graph.facebook.com/me

Response:

{
  "id": "102003656685359", 
  "name": "Benjamin Foster", 
  "first_name": "Benjamin", 
  "last_name": "Foster", 
  "link": "http://www.facebook.com/profile.php?id=100003086675319", 
  "bio": "", 
  "gender": "male", 
  "email": "email@somedomain.com", 
  "timezone": 1, 
  "locale": "en_GB", 
  "verified": true, 
  "updated_time": "2012-02-06T18:41:09+0000", 
  "type": "user"
}

You can also choose the fields you want returned using the fields query parameter:

https://graph.facebook.com/me?fields=id,name

Further Documentation - http://developers.facebook.com/docs/reference/api/user/

Tool for testing api calls - http://developers.facebook.com/tools/explorer

Windows Live

OAuth Version: 2.0
OAuth API Details: http://msdn.microsoft.com/en-us/library/hh243647.aspx

Registering your application

Windows Live Application Name

  • You will then be presented with your “Client ID” and “Client Secret”

Windows Live API Keys

  • Click the “Application Settings Page” link and select “API Settings” from the menu on the left
  • Add your “Redirect Domain” and click Save.

Windows Live API Settings

Authorized OAuth Response

{
	"access_token":"xxxxxxxx",
	"authentication_token":"xxxxxxxx",
	"expires_in":3600,
	"scope":"wl.basic wl.emails",
	"token_type":"bearer"
}

Getting user profile information

By default the user API does not include the user’s email address. To access this you need to pass the “wl.email” scope when requesting an access token.

Example:

GET https://apis.live.net/v5.0/me?access_token=xxxxxxx

Response:

{
   "id": "0f964d03c991fba5", 
   "name": "Ben Foster", 
   "first_name": "Ben", 
   "last_name": "Foster", 
   "link": "http://profile.live.com/cid-0f964d03c991fba5/", 
   "gender": "male", 
   "emails": {
      "preferred": "email@somedomain.com", 
      "account": "email@somedomain.com", 
      "personal": null, 
      "business": null
   }, 
   "locale": "en_GB", 
   "updated_time": "2012-02-29T16:54:53+0000"
}

Further Documentation - http://msdn.microsoft.com/en-us/library/hh243648.aspx#user

© 2022 Ben Foster