This sample shows how to connect a Windows Phone 8.0 app to Facebook, Google and Microsoft accounts. The main features: Login/Logout and an about page with feedback, share in social networks, review and share by email.
Download C# (19.9 MB)
Introduction
This sample shows how to connect a Windows Phone 8.0 app to Facebook, Google and Microsoft account.
Main Features: Login/Logout and an about page with feedback, share in social networks, review and share by email.
Building the Sample
You only need Visual Studio 2012/Visual Studio 2013 and Windows 8/Windows 8.1, both the RTM version.
This sample requires the installation for Live SDK (Downloads).
Description
This sample shows how to connect a Windows Phone 8.0 app to Facebook, Google and Microsoft accounts.
Main Features
- Login/Logout (for logout I added a workarround to fix the logout providers from the SDKs!)
- An About page with feedback, share in social networks, review and share by email (not important here, but is incluided in code)
Note: This sample uses MVVM Light and Cimbalino Windows Phone Toolkit.
For this sample the following was used:
- Facebook SDK for Windows Phone (Facebook SDK for Windows Phone)
- Google APIs Auth Client and Google APIs OAuth2 Client (Google APIs Auth Client Library and Google APIs OAuth2 Client Library1.6.0-beta)
- Live SDK (onedrive)
For each provider it is necessry to get the app id/client id/client secret in their websites.
For Google go to https://console.developers.google.com/project and create a new project (APIs & auth > credentials).
For Facebook go to Facebook Developers and create a new app.
For Live SDK go to Sign in and create one or use an existing app.
Before you start you should change the Constant file to add client ids / client secret / app id, without it the app fails!!
This file is inside the Resource folder.
C#
- /// <summary>
- /// Defines the constants strings used in the app.
- /// </summary>
- public class Constants
- {
- /// <summary>
- /// The facebook app id.
- /// </summary>
- public const string FacebookAppId = "<app id>";
- /// <summary>
- /// The google client identifier.
- /// </summary>
- public const string GoogleClientId = "<client id>";
- /// <summary>
- /// The google token file name.
- /// </summary>
- public const string GoogleTokenFileName = "Google.Apis.Auth.OAuth2.Responses.TokenResponse-user";
- /// <summary>
- /// The google client secret.
- /// </summary>
- public const string GoogleClientSecret = "<client secret>";
- /// <summary>
- /// The microsoft client identifier.
- /// </summary>
- public const string MicrosoftClientId = "<client id>";
- ...
- }
Now let's see how to connect to each provider. For help, I created a SessionService that managed the Login and Logout using a provider value, this is nice because in LoginView I set the buttons to the same command and for each command I set the provider in commandparameter. With it the LoginView and LoginViewModel are clearer and simpler. Another thing is for example if I need to connect to my server to accept the user I can do it in the session manager after the authentication, without adding the code to each provider.
The classes created:
- FacebookService has all code related with authentication with Facebook account
- MicrosoftService has all code related with authentication with Microsoft account
- GoogleService has all code related with authentication with Google account
- SessionService call the methods login or logout for the provide requested
The FacebookService is:
C#
- /// <summary>
- /// Defines the Facebook Service.
- /// </summary>
- public class FacebookService : IFacebookService
- {
- private readonly ILogManager _logManager;
- private readonly FacebookSessionClient _facebookSessionClient;
- /// <summary>
- /// Initializes a new instance of the <see cref="FacebookService"/> class.
- /// </summary>
- /// <param name="logManager">
- /// The log manager.
- /// </param>
- public FacebookService(ILogManager logManager)
- {
- _logManager = logManager;
- _facebookSessionClient = new FacebookSessionClient(Constants.FacebookAppId);
- }
- /// <summary>
- /// The login sync.
- /// </summary>
- /// <returns>
- /// The <see cref="Task"/> object.
- /// </returns>
- public async Task<Session> LoginAsync()
- {
- Exception exception;
- Session sessionToReturn = null;
- try
- {
- var session = await _facebookSessionClient.LoginAsync("user_about_me,read_stream");
- sessionToReturn = new Session
- {
- AccessToken = session.AccessToken,
- Id = session.FacebookId,
- ExpireDate = session.Expires,
- Provider = Constants.FacebookProvider
- };
- return sessionToReturn;
- }
- catch (InvalidOperationException)
- {
- throw;
- }
- catch (Exception ex)
- {
- exception = ex;
- }
- await _logManager.LogAsync(exception);
- return sessionToReturn;
- }
- /// <summary>
- /// Logouts this instance.
- /// </summary>
- public async void Logout()
- {
- Exception exception = null;
- try
- {
- _facebookSessionClient.Logout();
- // clean all cookies from browser, is a workarround
- await new WebBrowser().ClearCookiesAsync();
- }
- catch (Exception ex)
- {
- exception = ex;
- }
- if (exception != null)
- {
- await _logManager.LogAsync(exception);
- }
- }
- }
Note: In logout I added a workarround to clear all cookies in browser, if I don´t this in the first time you can login with account you want but in the next time it will use the account used in last login.
The GoogleService is:
C#
- /// <summary>
- /// The google service.
- /// </summary>
- public class GoogleService : IGoogleService
- {
- private readonly ILogManager _logManager;
- private readonly IStorageService _storageService;
- private UserCredential _credential;
- private Oauth2Service _authService;
- private Userinfoplus _userinfoplus;
- /// <summary>
- /// Initializes a new instance of the <see cref="GoogleService" /> class.
- /// </summary>
- /// <param name="logManager">The log manager.</param>
- /// <param name="storageService">The storage service.</param>
- public GoogleService(ILogManager logManager, IStorageService storageService)
- {
- _logManager = logManager;
- _storageService = storageService;
- }
- /// <summary>
- /// The login async.
- /// </summary>
- /// <returns>
- /// The <see cref="Task"/> object.
- /// </returns>
- public async Task<Session> LoginAsync()
- {
- Exception exception = null;
- try
- {
- // Oauth2Service.Scope.UserinfoEmail
- _credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets
- {
- ClientId = Constants.GoogleClientId,
- ClientSecret = Constants.GoogleClientSecret
- }, new[] { Oauth2Service.Scope.UserinfoProfile }, "user", CancellationToken.None);
- var session = new Session
- {
- AccessToken = _credential.Token.AccessToken,
- Provider = Constants.GoogleProvider,
- ExpireDate =
- _credential.Token.ExpiresInSeconds != null
- ? new DateTime(_credential.Token.ExpiresInSeconds.Value)
- : DateTime.Now.AddYears(1),
- Id = string.Empty
- };
- return session;
- }
- catch (TaskCanceledException taskCanceledException)
- {
- throw new InvalidOperationException("Login canceled.", taskCanceledException);
- }
- catch (Exception ex)
- {
- exception = ex;
- }
- await _logManager.LogAsync(exception);
- return null;
- }
- /// <summary>
- /// Gets the user information.
- /// </summary>
- /// <returns>
- /// The user info.
- /// </returns>
- public async Task<Userinfoplus> GetUserInfo()
- {
- _authService = new Oauth2Service(new BaseClientService.Initializer()
- {
- HttpClientInitializer = _credential,
- ApplicationName = AppResources.ApplicationTitle,
- });
- _userinfoplus = await _authService.Userinfo.V2.Me.Get().ExecuteAsync();
- return _userinfoplus;
- }
- /// <summary>
- /// The logout.
- /// </summary>
- public async void Logout()
- {
- await new WebBrowser().ClearCookiesAsync();
- if (_storageService.FileExists(Constants.GoogleTokenFileName))
- {
- _storageService.DeleteFile(Constants.GoogleTokenFileName);
- }
- }
- }
Note: In the logout for the Google provider there isn´t a logout method, the solution is to remove all cookies and remove the file created in the login operation.
The MicrosoftService is:
C#
- /// <summary>
- /// The microsoft service.
- /// </summary>
- public class MicrosoftService : IMicrosoftService
- {
- private readonly ILogManager _logManager;
- private LiveAuthClient _authClient;
- private LiveConnectSession _liveSession;
- /// <summary>
- /// Defines the scopes the application needs.
- /// </summary>
- private static readonly string[] Scopes = { "wl.signin", "wl.basic", "wl.offline_access" };
- /// <summary>
- /// Initializes a new instance of the <see cref="MicrosoftService"/> class.
- /// </summary>
- /// <param name="logManager">
- /// The log manager.
- /// </param>
- public MicrosoftService(ILogManager logManager)
- {
- _logManager = logManager;
- }
- /// <summary>
- /// The login async.
- /// </summary>
- /// <returns>
- /// The <see cref="Task"/> object.
- /// </returns>
- public async Task<Session> LoginAsync()
- {
- Exception exception = null;
- try
- {
- _authClient = new LiveAuthClient(Constants.MicrosoftClientId);
- var loginResult = await _authClient.InitializeAsync(Scopes);
- var result = await _authClient.LoginAsync(Scopes);
- if (result.Status == LiveConnectSessionStatus.Connected)
- {
- _liveSession = loginResult.Session;
- var session = new Session
- {
- AccessToken = result.Session.AccessToken,
- ExpireDate = result.Session.Expires.DateTime,
- Provider = Constants.MicrosoftProvider,
- };
- return session;
- }
- }
- catch (LiveAuthException ex)
- {
- throw new InvalidOperationException("Login canceled.", ex);
- }
- catch (Exception e)
- {
- exception = e;
- }
- await _logManager.LogAsync(exception);
- return null;
- }
- /// <summary>
- /// The logout.
- /// </summary>
- public async void Logout()
- {
- if (_authClient == null)
- {
- _authClient = new LiveAuthClient(Constants.MicrosoftClientId);
- var loginResult = await _authClient.InitializeAsync(Scopes);
- }
- _authClient.Logout();
- }
- }
The SessionService is:
C#


SharadPosted Jul 17, 2015, 3:58 AM
good one...
Vithal WadjePosted Jan 25, 2015, 12:11 AM
nice
Deepak VermaPosted Jun 30, 2014, 1:30 AM
Good article Sara
Prerana TiwariPosted Jun 23, 2014, 11:00 PM
Well explained..........
Bhavik PatelPosted Jun 10, 2014, 10:26 PM
Hey sara. Great shared. you have good article writing skills.. easy to understand...
Sara SilvaPosted Jun 5, 2014, 10:50 AM
Thanks :D
Premkumar EswaramurthiPosted Jun 2, 2014, 2:13 AM
Thanks for sharing this detailed explanation article
Rohatash KumarPosted Jun 2, 2014, 1:06 AM
Thanks for sharing a thoughtful and informative information.
Nimit JoshiPosted Jun 2, 2014, 12:51 AM
Very well explained information.. Easy to understand..
Lakshmanan Sethu SankaranarayanPosted May 31, 2014, 9:50 PM
Wow.Detailed explanation.Good one
Sara SilvaPosted May 31, 2014, 6:12 PM
Thanks! :D
Brij MishraPosted May 31, 2014, 9:06 AM
Very nice and detailed explanation. Thanks for sharing!!
Anil KumarPosted May 31, 2014, 3:40 AM
Very informative and nicely written ! Welcome to C#Corner community :)
Praveen KumarPosted May 30, 2014, 5:33 AM
Welcome Sara. Good to see professionals like you sharing knowledge and expertise with others.
Sara SilvaPosted May 30, 2014, 4:43 AM
Thanks :D
Former memberPosted May 30, 2014, 4:29 AM
very nice article Sara !
Shiju JosephPosted May 30, 2014, 2:08 AM
Good Work !!!
Dinesh BeniwalPosted May 30, 2014, 1:55 AM
Great work, Welcome to the C# Corner Sara.