No need for iframe, no need for WebBrowser control. Doing OAuth authentication to get user to consent connecting your App to their Facebook, Twitter, FourSquare is so easy in Windows 8 Store App Development. Here is how I connect my test app to FourSquare to get the Tips for a Venue.
1. Register your app in FourSquare Dev Portal
Go to https://foursquare.com/developers/apps and register your app. Below is the screenshot of what I put for my app. Note you don’t need a real Server for the Redirect URL, I just put http://localhost , cos what I care is to get the OAuth token embedded in the returned URL.
2. How to find Venue ID from FourSquare
Now I need the Venue ID to get the Tips, this is how I do it cos I find it just easier:
Go to https://foursquare.com/explore
Type the venue you’re looking for, and change the city if it’s in a different city , this is important to get exactly what you want. For example, I want to find ‘Emirates Palace’ in ‘Abu Dhabi’ , not in my current location (Dubai):
Now click the Venue that is the closest match. For me it’s the first result, but sometimes you want to get specific like the ballroom in Emirates Palace Hotel.
The Venue ID is embedded in the URL, see below:
3. Authenticate to FourSquare
Now finally comes the OAuth code that I said was easy. Here is how you use it in Windows Store JavaScript:
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 |
// Start OAuth authentication function authenticateIfRequired() { // comment this to cache OAuth token //RT.OAuthHelper.clearCache(); if (RT.OAuthHelper.isTokenExist()) { oauthToken = RT.OAuthHelper.getToken(); writeLog("CACHED TOKEN found: token = " + oauthToken); return; } var startUri = new Windows.Foundation.Uri(RT.OAuthHelper.getAuthUrl()); var endUri = new Windows.Foundation.Uri(RT.OAuthHelper.getRedirectUrl()); authWeb.WebAuthenticationBroker.authenticateAsync( authWeb.WebAuthenticationOptions.none, startUri, endUri) .done(function (result) { RT.OAuthHelper.saveToken(result.responseData); oauthToken = RT.OAuthHelper.getToken(); writeLog("SUCCESS: token = " + oauthToken); }, function (error) { writeLog("ERROR: " + error); }); } |
Where authWeb is defined at the top as a namespace alias:
1 |
var authWeb = Windows.Security.Authentication.Web; |
This will give you this magic screen:
You will notice that I used a WinRT component there. This is like my “Session Manager”. I can reference a WinRT static class anywhere in my multiple JavaScripts to make it like a Singleton Session Manager (if you do this in HTML5/JavaScript, you will need to include “oAuthHelper.js” in every html page that needs it. By writing a WinRT component in C#, I can call it from any JavaScript simply by using its namespace like the above.
Here is my WinRT C# code for OAuthHelper:
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 53 54 |
public sealed class OAuthHelper { const string APP_AUTH_URL = @"https://foursquare.com/oauth2/authenticate?client_id=[CLIENT_ID]&response_type=token&redirect_uri=https://localhost"; const string REDIRECT_URL = @"https://localhost"; const string KEY_TOKENEXIST = "TOKEN_DOES_EXIST"; const string KEY_TOKENVALUE = "TOKEN_VALUE"; public static string GetAuthUrl() { return APP_AUTH_URL; } public static string GetRedirectUrl() { return REDIRECT_URL; } public static bool IsTokenExist() { bool tokenThere = false; var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; if (localSettings.Values.ContainsKey(KEY_TOKENEXIST)) { tokenThere = (bool) localSettings.Values[KEY_TOKENEXIST]; } return tokenThere; } public static void SaveToken(string responseData) { var url = responseData; var indexTokenWord = url.IndexOf("access_token=") + 13; var token = url.Substring(indexTokenWord); var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; localSettings.Values[KEY_TOKENEXIST] = true; localSettings.Values[KEY_TOKENVALUE] = token; } public static string GetToken() { var token = string.Empty; var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; if (localSettings.Values.ContainsKey(KEY_TOKENVALUE)) { token = (string)localSettings.Values[KEY_TOKENVALUE]; } return token; } public static void ClearCache() { var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; localSettings.Values.Remove(KEY_TOKENEXIST); localSettings.Values.Remove(KEY_TOKENVALUE); } } |
4. Use Token to Get the Tips
Once I have an OAuth Token, I saved that in the AppSetting, and now I just need to append this token to every FourSquare API request:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function getTipsViaOnlineApiCall() { var emirates = RT.VenueHelper.getEmiratesVenueId(); RT.VenueHelper.getVenueTipsAsync(emirates) .done(function (strJson) { // save to local file RT.LocalFileHelper.writeStringToFile("emirates-Tips.txt", strJson); writeLog("TIPS RESPONSE: " + strJson); var json = JSON.parse(strJson); var tipsList = new WinJS.Binding.List(json.response.tips.items); var listview = tips.winControl; listview.itemDataSource = tipsList.dataSource; }); } |
As you can see, I cached the response so that next time I can show the Tips without going through Internet, here is the code for the VenueHelper and LocalFileHelper WinRT C# components:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public sealed class VenueHelper { const string TIP_URL_TEMPLATE = @"https://api.foursquare.com/v2/venues/{0}/tips?oauth_token={1}&v={2}"; public static string GetEmiratesVenueId() { return "4b07d6d2f964a5205f0023e3"; } public static IAsyncOperation<string> GetVenueTipsAsync(string venueId) { return Task.Run<string>( async () => { var json = string.Empty; var request = string.Format(TIP_URL_TEMPLATE, venueId, OAuthHelper.GetToken(), DateTime.Now.ToString("yyyyMMdd")); var client = new HttpClient(); json = await client.GetStringAsync(request); return json; }).AsAsyncOperation(); } } |
And this is the code for the LocalFileHelper:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public sealed class LocalFileHelper { public static IAsyncAction WriteStringToFile(string fileName, string contents) { return Task.Run(async () => { var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; var file = await localFolder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.ReplaceExisting); await Windows.Storage.FileIO.WriteTextAsync(file, contents); }).AsAsyncAction(); } public static IAsyncOperation<string> ReadStringFromFile(string fileName) { return Task<string>.Run(async () => { var json = string.Empty; var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; var file = await localFolder.GetFileAsync(fileName); json = await Windows.Storage.FileIO.ReadTextAsync(file); return json; }).AsAsyncOperation(); } } |
And this is the app in action:
Hope it helps you in building your Windows 8 Store Apps with Social features 🙂
Pingback: Windows 8: How to do OAuth authentication in 1 line of code - Z & his Startup
Pingback: OAuth Resources « skater coder
Thank you! Your article has been very useful for the development of my own app.
can u give the solution as zip file?