Universal App - 整合 Facebook Login

Universal App - 整合 Facebook Login

在撰寫 Silverlight Phone App 時可以藉由<[WindowsPhone] 新版整合Facebook+取得token>該篇介紹

實作出 Phone App 與 Facebook App 互動,來取得帳號驗證與宣告使用的權限。

Facebook 官方網站 也是這樣的教學。

但有一次我遇到了 Facebook App 在改版後不小心拿掉了這個功能,造成客戶哇哇叫,因此,

這一篇將介紹藉由新的元件:WebAuthenticationBroker,實作 Web OAuth 的驗證。

 

WebAuthenticationBroker

     適用於驗證運作,例如:OAuth。可以在程式裡啟動第三方程式驗證或跨不同的程式之間進行驗證。

範例程式可參考<Web authentication broker sample>。藉由它可以實現 single sign on (SSO) connections。

 

重要的方法與屬性:

名稱 說明
AuthenticateAndContinue(Uri) Starts the authentication operation with one input.
AuthenticateAndContinue(Uri, Uri) Starts the authentication operation with two inputs.
AuthenticateAndContinue(Uri, Uri, ValueSet, WebAuthenticationOptions) Starts the authentication operation with four inputs.
AuthenticateAsync(WebAuthenticationOptions, Uri) Starts the asynchronous authentication operation with two inputs.
You can call this method multiple times in a single application or across multiple applications at the same time.
AuthenticateAsync(WebAuthenticationOptions, Uri, Uri) Starts the asynchronous authentication operation with three inputs.
AuthenticateSilentlyAsync(Uri) Starts the asynchronous authentication operation silently (no UI will be shown) with one input.
AuthenticateSilentlyAsync(Uri, WebAuthenticationOptions) Starts the asynchronous authentication operation silently (no UI will be shown) with two inputs.
GetCurrentApplicationCallbackUri Gets the current application callback URI.

其中可以看到幾個重要的參數:

a. WebAuthenticationOptions

      The options for the authentication operation. 具有五種類型:

Member Value Description
None 0 No options are requested.
SilentMode 1

Tells the web authentication broker to not render any UI.

This option will throw an exception if used with AuthenticateAndContinue; AuthenticateSilentlyAsync,                       which includes this option implicitly, should be used instead.

UseTitle 2 Tells the web authentication broker to return the window title string of the webpage in the ResponseData property.
UseHttpPost 4 Tells the web authentication broker to return the body of the HTTP POST in the ResponseData property. For use with single sign-on (SSO) only.
UseCorportateNetwork 8 Tells the web authentication broker to render the webpage in an app container that supports privateNetworkClientServer, enterpriseAuthentication, and sharedUserCertificate capabilities. Note the application that uses this flag must have these capabilities as well.

 

b.  requestUri:

      The starting URI of the web service. This URI must be a secure address of https://.。

c. callbackUri:

      The callback URI that indicates the completion of the web authentication. The broker matches this URI against every URI that it is about to navigate to.

      The broker never navigates to this URI, instead the broker returns the control back to the application when the user clicks a link or a web server redirection is made.

 

實作步驟如下:

1. 先至 Facebook developer 註冊帳號,並且建立一個 Application,取得對應的 App ID,如下圖:

    image

   

 

2. 開啟 Dev center 為 App 註冊一個新的 Application 取得對應的 Product ID,並註冊於 Facebook 的 Application 授權 Apps 裡;

     建立一個新的 Application (或是使用既有的 Application),需要上傳一個正常可的 *.appx 來取得 Product ID

   a. Windows:

       a-1. 開啟應用程式的編輯,如下圖;

                image

       a-2. 選擇「服務」->選擇「瀏覽線上服務網站」:

                image

        a-3. 將「封裝 SSID」複製起來,加入至 Facebook Application 援權平台。

                 image

        a-4. 需要將 App 透過 Visual studio 將目前 Windows 的專案與 Dev Center 建立好的 Application 綁定起來,如下:

                 image

                輸入 dev center 註冊的 Microsoft account,並且將剛建立(或舊的) Application 與 App 關聯,這樣 SSID 才會一致

 

   b. Windows Phone:

        b-1. 做法概念類似 Windows ,使用舊的或新建立的 Application 來取得 Product ID,開啟後選擇「詳細資料」如下圖:

                 image

                 如果您使用的只是要擷取來測試用,那可以使用 Windows Project 的 Package.appxmanifest 裡定義的 <mp:PhoneIdentity PhoneProductId />如下圖:

                 image    

 

 

    c. 向 Facebook Application 註冊可授權的 App platform,如下:

        image

         Windows Store ID:需要拿掉 ms-app://,只需要填寫入 ms-app:// 後面的部分;

         Windows Phone Store ID [Beta]:則需要將 Product ID 中的「-」符號去掉只留原始值;

 

 

3. 分別準備對於 Facebook Login OAuth 驗證專用的 URL;

參數
client_id Facebook app id
redirect_uri 代表驗證完畢後要導向的 URL。針對 Windows/Windows Phone App 二種導向的 URL 不同:
〉Windows:放入 SSID,要記得 URL Encoding;
〉Windows Phone:msft-{product id}://authorize;
response_type 填入 token。這個部分參考 Facebook 的文件說明:。
scope 填寫要請求 Facebook 給予這個 App 操作的權限,例如:public_profile,email。

     由於操作 WebAuthenticationBroker 需要給予一個 request uri,所以藉由上述的參數建立專屬於 Windows 與 Windows Phone 的 URL。

〉Windows:

private static String facebookAppId = "";
private static String ssID = "";

 

 
public static async Task WinStoreFBLogin(CoreDispatcher dispatcher)
{
    // 組合需要的參數,SSID 要記得先藉由 URL Encoding
    String request = "https://www.facebook.com/dialog/oauth?" +
                    "client_id=" + facebookAppId +
                    "&redirect_uri=" + ssID + 
                    "&response_type=token" +
                    "&display=popup" +
                    "&scope=public_profile,email";
    Uri authUrl = new Uri(request);

 
    // 藉由 WebAuthenticationBroker 請求驗證
    var result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, authUrl);
    if (result.ResponseStatus == WebAuthenticationStatus.Success)
    {
        // 拆解取得 Facebook 回傳的 access_token 與  expires_in
        String[] data = result.ResponseData.Split(new String[] { "#" }, StringSplitOptions.RemoveEmptyEntries);
        String[] fbData = data[1].Split('&');
        String accessToken = fbData[0].Replace("access_token=", "");
        String expire = fbData[1].Replace("expires_in", "");

 
        dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
        {
            MessageDialog dialog = new MessageDialog("success", "fb login");
            dialog.ShowAsync();
        });
    }
    else
    {
        dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
        {
            MessageDialog dialog = new MessageDialog(result.ResponseData, "fb error");
            dialog.ShowAsync();
        });
    }
}

 

〉Windows Phone:

private static String productId = "";
private static String facebookAppId = "";

 
public static async Task WP81FBLogin(CoreDispatcher dispatcher)
{
    // 組合要請求回傳的 callback
    string redirectUri = "msft-" + productId + "://authorize";
    String request = "https://www.facebook.com/dialog/oauth?" +
                     "client_id=" + facbeookAppId +
                     "&redirect_uri=" + redirectUri +
                     "&response_type=token" +
                     // "&display=popup" +
                     "&scope=public_profile,email";
    Uri authUrl = new Uri(request);
    Uri callbackUrl = new Uri(redirectUri);
if WINDOWS_PHONE_APP
    // AuthenticateAndContinue 僅支援 Windows Phone 使用,要記得給 callbackUrl
    // 這樣驗證完畢後才會自動返回程式,這個部分與 Windows Store App 不一樣
    WebAuthenticationBroker.AuthenticateAndContinue(authUrl, callbackUrl);
endif
}

 

4. 在 App.xaml.cs 中註冊對應的事件;

     由於 Windows Phone  App 使用 WebAuthenticationBroker 是會開啟其他的 Web app,所以要加上下方程式才能取得 Windows Phone App 登入

Facebook Login 後取得的 access_token 與 expire_time,如下程式碼:

protected override void OnActivated(IActivatedEventArgs args)
{
    base.OnActivated(args);

 
    string fbAccessToken = String.Empty;

 
    // 判斷是否 App 被啟動來自 WebAuthenticationBrokerContinuation
    if (args.Kind == ActivationKind.WebAuthenticationBrokerContinuation)
    {
        // 轉換參數
        WebAuthenticationBrokerContinuationEventArgs webArgs = args as 
                                                WebAuthenticationBrokerContinuationEventArgs;
        if (webArgs.WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
        {
            // 拆解出 access_token 與 expires_in 二個重要參數
            String[] data = webArgs.WebAuthenticationResult.ResponseData.Split(new String[] { "#" }, 
                                                        StringSplitOptions.RemoveEmptyEntries);
            String[] fbData = data[1].Split('&');
            String accessToken = fbData[0].Replace("access_token=", "");
            String expire = fbData[1].Replace("expires_in", "");

 
            fbAccessToken = accessToken;
        }
    }

 
    // 利用 ApplicationDataContainder 將 token 保存起來
    ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
    if (localSettings.Values.ContainsKey("wp_fb_token") == false)
    {
        localSettings.Values.Add("wp_fb_token", fbAccessToken);
    }
    else
    {
        localSettings.Values["wp_fb_token"] = fbAccessToken;
    }

 
    // 以下用於通知畫面是否已完成取得 Facebook Token 的任務。
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame != null)
    {
        MainPage page = rootFrame.Content as MainPage;
        if (page != null)
        {
            page.CheckFbAccess();
        }
    }
}

 

5. 測試;

〉Windows:

     image image

〉Windows Phone:

     11 02 01 03

 

[範例程式]

 

======

以上是分享如何在 Universal App 整合 Facebook Login 的方式,希望對大家有所幫助。

 

References:

Authentication and User Identity (XAML) (重要)

Quickstart: Connecting to an online identity provider (C#/C++/VB) (重要)

Using Live Connect in your Windows Store apps using C++, C#, or Visual Basic.

Facebook login for Windows Store apps

Metro Style App: 使用 WebAuthenticationBroker 做 Facebook 帳號驗證

Facebook Login Version

WebAuthenticationBroker & Facebook

Use WebAuthenticationBroker to do single sign on (SSO) connections

How to use the WebAuthenticationBroker for oAuth in a Windows Phone Runtime WP8.1 app

Smart Cards and Virtual Smart Cards

Fingerprint (biometric) authentication

 

Dotblogs Tags: