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):
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
Not all of this information is provided in the original request token response so an additional API call is usually required.
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”
- 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)
- 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.
- 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.
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
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.
- You’ll then be provided with your OAuth settings. The “Consumer Key” and “Consumer Secret” are necessary to make OAuth requests.
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
OAuth Version: 1.0a
OAuth API Details: https://developer.linkedin.com/documents/oauth-overview
Registering your application
- Go to https://www.linkedin.com/secure/developer?newapp=
- Complete the application form. The Javascript API domain must be a valid domain (such as your test domain).
- You can then click your application name to view your “API Key” and “Secret Key”
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
OAuth Version: 2.0
OAuth API Details: http://developers.facebook.com/docs/authentication
Registering your application
- Go to https://developers.facebook.com/apps
- Click “Create new app”
- The App Settings page displays your “App ID” and “App Secret”
- Enter the domain of your web application (e.g. your test domain)
- Under “Select how your app integrates with Facebook” tick “Website” and enter your domain (facebook will only redirect to urls at this domain)
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
- Go to https://manage.dev.live.com/AddApplication.aspx
- Give your application a name
- You will then be presented with your “Client ID” and “Client Secret”
- Click the “Application Settings Page” link and select “API Settings” from the menu on the left
- Add your “Redirect Domain” and click Save.
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