2014-10-02 3 views
0

Я работаю над приложением Windows Phone 8, и я хотел бы интегрировать вход в facebook в приложение. Я скачал Facebook и Facebook.Client nuget пакеты.Windows phone 8 facebookdk login and relogin

Я следовал этому руководству http://facebooksdk.net/docs/windows/tutorial/ и реализовал функцию входа в систему. Мой код выглядит так:

async private void btnFacebookLogin_Click(object sender, RoutedEventArgs e) 
{ 
    if (!App.isAuthenticated) 
    { 
     App.isAuthenticated = true; 
     await Authenticate(); 
    } 
} 


private async Task Authenticate() 
{ 
    string message = String.Empty; 
    try 
    { 
     session = await App.FacebookSessionClient.LoginAsync("user_about_me,read_stream"); 
     App.AccessToken = session.AccessToken; 
     App.FacebookId = session.FacebookId; 

     Frame.Navigate(typeof(LandingPage)); 
    } 
    catch (InvalidOperationException e) 
    { 
     message = "Login failed! Exception details: " + e.Message; 
     MessageDialog dialog = new MessageDialog(message); 
     dialog.ShowAsync(); 
    } 
} 

Вход в систему работает нормально, но когда я закрываю приложение и запускаю его снова, объект сеанса теряется.
Когда я нажимаю кнопку Login и вызывается метод Authenticate(), диалоговое окно входа в Facebook не отображается, и метод App.FacebookSessionClient.LoginAsync («user_about_me, read_stream») немедленно возвращает сеанс. Это не очень приятно для пользователя.
В приложении находится кнопка «Вход в систему Facebook», и после щелчка отображается зарегистрированный пользователь без какой-либо формы входа или взаимодействия с пользователем.
Я не знаю, где хранится сеанс и как проверить, доступен ли какой-либо старый сеанс, и будет возвращен без диалога входа в систему Facebook.

Есть ли способ, как это сделать?

Это моя версия FacebookSessionClient

#region Assembly Facebook.Client.dll, v0.9.1.0 
// D:\Work\packages\Facebook.Client.0.9.1-alpha\lib\wp8\Facebook.Client.dll 
#endregion 

using System; 
using System.Diagnostics; 
using System.Threading.Tasks; 

namespace Facebook.Client 
{ 
    public class FacebookSessionClient 
    { 
     public FacebookSessionClient(string appId); 

     public string AppId { get; set; } 
     public FacebookSession CurrentSession { get; } 
     public bool LoginInProgress { get; set; } 

     [DebuggerStepThrough] 
     public Task<FacebookSession> LoginAsync(); 
     [DebuggerStepThrough] 
     public Task<FacebookSession> LoginAsync(string permissions); 
     public void LoginWithApp(); 
     public void LoginWithApp(string permissions); 
     public void LoginWithApp(string permissions, string state); 
     // 
     // Summary: 
     //  Log a user out of Facebook. 
     public void Logout(); 
    } 
} 

ответ

1

Вы можете сделать так:

Шаг 1:

_client = new FacebookSessionClient(yourAppId); 

Шаг 2: (Добавить LoggedIn недвижимость FacebookSessionClient, как показано ниже)

public bool LoggedIn 
{ 
    get 
    { 
     return CurrentSession != null && CurrentSession.Expires > DateTime.Now; 
    } 
} 

Я также изменил FacebookSessionClient заменяющего существующего CurrentSession свойство с

public FacebookSession CurrentSession 
{ 
    get 
    { 
     return FacebookSessionCacheProvider.Current.GetSessionData(); 
    } 
} 

Шага 3:

if(!_client.LoggedIn) 
{ 
    _client.LoginAsync("basic_info,publish_actions,read_stream,user_photos"); 
} 
else 
{ 
    //just use the _client variable 
} 

Facebook клиент заботами, чтобы сохранить его сессия и перезагрузить его на следующий раз, когда вы открываете приложение.

Это то, что я имею в моем FacebookSessionClient.cs

//----------------------------------------------------------------------- 
// <copyright file="FacebookSessionClient.cs" company="The Outercurve Foundation"> 
// Copyright (c) 2011, The Outercurve Foundation. 
// 
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at 
//  http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License. 
// </copyright> 
// <author>Nathan Totten (ntotten.com) and Prabir Shrestha (prabir.me)</author> 
// <website>https://github.com/facebook-csharp-sdk/facbook-winclient-sdk</website> 
//----------------------------------------------------------------------- 

using System; 
using System.Collections.Generic; 
using System.Diagnostics.CodeAnalysis; 
using System.IO; 
using System.Linq; 
using System.Reflection; 
using System.Text; 
using System.Threading.Tasks; 
#if NETFX_CORE 
using Windows.Security.Authentication.Web; 
#endif 

namespace Facebook.Client 
{ 
    public class FacebookSessionClient 
    { 
     public string AppId { get; set; } 
     public bool LoginInProgress { get; set; } 

     public FacebookSession CurrentSession 
     { 
      get 
      { 
       return FacebookSessionCacheProvider.Current.GetSessionData(); 
      } 
     } 

     public FacebookSessionClient(string appId) 
     { 
      if (String.IsNullOrEmpty(appId)) 
      { 
       throw new ArgumentNullException("appId"); 
      } 
      AppId = appId; 

      // Send analytics to Facebook 
      SendAnalytics(appId); 
     } 

     private static bool AnalyticsSent = false; 

     private void SendAnalytics(string FacebookAppId = null) 
     { 
      try 
      { 
       if (!AnalyticsSent) 
       { 
        AnalyticsSent = true; 

#if !(WINDOWS_PHONE) 
        Version assemblyVersion = typeof(FacebookSessionClient).GetTypeInfo().Assembly.GetName().Version; 
#else 
        string assemblyVersion = Assembly.GetExecutingAssembly().FullName.Split(',')[1].Split('=')[1]; 
#endif 
        string instrumentationURL = String.Format("https://www.facebook.com/impression.php/?plugin=featured_resources&payload=%7B%22resource%22%3A%22microsoft_csharpsdk%22%2C%22appid%22%3A%22{0}%22%2C%22version%22%3A%22{1}%22%7D", 
          FacebookAppId == null ? String.Empty : FacebookAppId, assemblyVersion); 

        HttpHelper helper = new HttpHelper(instrumentationURL); 

        // setup the read completed event handler to dispose of the stream once the results are back 
        helper.OpenReadCompleted += (o, e) => { if (e.Error == null) using (var stream = e.Result) { }; }; 
        helper.OpenReadAsync(); 
       } 
      } 
      catch { } //ignore all errors 
     } 

#if WP8 
     public void LoginWithApp() 
     { 
      LoginWithApp(null); 
     } 

     public void LoginWithApp(string permissions) 
     { 
      LoginWithApp(permissions, null); 
     } 

     public void LoginWithApp(string permissions, string state) 
     { 
      AppAuthenticationHelper.AuthenticateWithApp(this.AppId, permissions, state); 
     } 
#endif 

     public async Task<FacebookSession> LoginAsync() 
     { 
      return await LoginAsync(null, false); 
     } 

     public async Task<FacebookSession> LoginAsync(string permissions) 
     { 
      return await LoginAsync(permissions, false); 
     } 

     internal async Task<FacebookSession> LoginAsync(string permissions, bool force) 
     { 
      if (LoginInProgress) 
      { 
       throw new InvalidOperationException("Login in progress."); 
      } 

      LoginInProgress = true; 
      try 
      { 
       var session = FacebookSessionCacheProvider.Current.GetSessionData(); 
       if (session == null) 
       { 
        // Authenticate 
        var authResult = await PromptOAuthDialog(permissions, WebAuthenticationOptions.None); 

        FacebookClient client = new FacebookClient(authResult.AccessToken); 
        var parameters = new Dictionary<string, object>(); 
        parameters["fields"] = "id"; 

        var result = await client.GetTaskAsync("me", parameters); 
        var dict = (IDictionary<string, object>)result; 

        session = new FacebookSession 
        { 
         AccessToken = authResult.AccessToken, 
         Expires = authResult.Expires, 
         FacebookId = (string)dict["id"], 
        }; 

       } 
       else 
       { 
        // Check if we are requesting new permissions 
        bool newPermissions = false; 
        if (!string.IsNullOrEmpty(permissions)) 
        { 
         var p = permissions.Split(','); 
         newPermissions = 
          session.CurrentPermissions.Join(p, s1 => s1, s2 => s2, (s1, s2) => s1).Count() != p.Length; 
        } 

        // Prompt OAuth dialog if force renew is true or 
        // if new permissions are requested or 
        // if the access token is expired. 
        if (force || newPermissions || session.Expires <= DateTime.UtcNow) 
        { 
         var authResult = await PromptOAuthDialog(permissions, WebAuthenticationOptions.None); 
         if (authResult != null) 
         { 
          session.AccessToken = authResult.AccessToken; 
          session.Expires = authResult.Expires; 
         } 
        } 
       } 

       // Set the current known permissions 
       if (!string.IsNullOrEmpty(permissions)) 
       { 
        var p = permissions.Split(','); 
        session.CurrentPermissions = session.CurrentPermissions.Union(p).ToList(); 
       } 

       // Save session data 
       FacebookSessionCacheProvider.Current.SaveSessionData(session); 

      } 
      catch (Exception x) 
      { 
       string msg = x.Message; 
      } 
      finally 
      { 
       LoginInProgress = false; 
      } 

      return CurrentSession; 
     } 

     /// <summary> 
     /// Log a user out of Facebook. 
     /// </summary> 
     [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout", Justification = "Logout is preferred by design")] 
     public void Logout() 
     { 
      try 
      { 
       FacebookSessionCacheProvider.Current.DeleteSessionData(); 
      } 
      catch (Exception x) 
      { 

      } 
     } 

     private async Task<FacebookOAuthResult> PromptOAuthDialog(string permissions, WebAuthenticationOptions options) 
     { 
      // Use WebAuthenticationBroker to launch server side OAuth flow 

      Uri startUri = GetLoginUrl(permissions); 
      Uri endUri = new Uri("https://www.facebook.com/connect/login_success.html"); 

      var result = await WebAuthenticationBroker.AuthenticateAsync(options, startUri, endUri); 


      if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp) 
      { 
       throw new InvalidOperationException(); 
      } 
      else if (result.ResponseStatus == WebAuthenticationStatus.UserCancel) 
      { 
       throw new InvalidOperationException(); 
      } 

      var client = new FacebookClient(); 
      var authResult = client.ParseOAuthCallbackUrl(new Uri(result.ResponseData)); 
      return authResult; 
     } 

     private Uri GetLoginUrl(string permissions) 
     { 
      var parameters = new Dictionary<string, object>(); 
      parameters["client_id"] = AppId; 
      parameters["redirect_uri"] = "https://www.facebook.com/connect/login_success.html"; 
      parameters["response_type"] = "token"; 
#if WINDOWS_PHONE 
      parameters["display"] = "touch"; 
      parameters["mobile"] = true; 
#else 
      parameters["display"] = "popup"; 
#endif 

      // add the 'scope' only if we have extendedPermissions. 
      if (!string.IsNullOrEmpty(permissions)) 
      { 
       // A comma-delimited list of permissions 
       parameters["scope"] = permissions; 
      } 

      var client = new FacebookClient(); 
      return client.GetLoginUrl(parameters); 
     } 

     /// <summary> 
     /// client.GetTaskAsync(path, parameters); 
     /// </summary> 
     /// <param name="path"> example: "me"</param> 
     /// <param name="parameters">example: "basic_info" or "basic_info, other_parameters"</param> 
     /// <returns>Dictionary with result</returns> 
     public async Task<IDictionary<string, object>> GetTaskAsync(string path, Dictionary<string, object> parameters) 
     { 
      FacebookClient client = new FacebookClient(CurrentSession.AccessToken); 
      var result = await client.GetTaskAsync(path, parameters); 
      var dict = (IDictionary<string, object>)result; 
      return dict; 
     } 
     /// <summary> 
     /// client.PostAsync(path, parameters); 
     /// </summary> 
     /// <param name="path">example: "me"</param> 
     /// <param name="parameters">example: "basic_info" or "basic_info, other_parameters"</param> 
     /// <returns>Dictionary with result</returns> 
     public async Task<IDictionary<string, object>> PostTaskAsync(string path, Dictionary<string, object> parameters) 
     { 
      FacebookClient client = new FacebookClient(CurrentSession.AccessToken); 
      TaskCompletionSource<object> task = new TaskCompletionSource<object>(); 
      client.PostCompleted += (sen, ev) => 
             { 
              if (ev.Cancelled) task.TrySetCanceled(); 
              if (ev.Error != null) task.TrySetException(ev.Error); 
              task.TrySetResult(ev.GetResultData()); 
             }; 
      client.PostAsync(path, parameters); 
      var result = await task.Task; 
      var dict = (IDictionary<string, object>)result; 
      return dict; 
     } 

     public bool LoggedIn 
     { 
      get 
      { 
       return CurrentSession != null && CurrentSession.Expires > DateTime.Now; 
      } 
     } 
    } 
} 
+0

Класс FacebookSessionClient не обладает свойством LoggedIn. –

+0

Просто чтобы убедиться, что он всегда работает, проверьте мой обновленный ответ. Я разместил свой настраиваемый FacebookSessionClient, который улучшает обработку CurrentSession. – csharpwinphonexaml

+0

Я не знаю, если я точно пойду за тобой. Это ваш собственный FacebookSessionClient, или это FacebookSessionClient, который вы загрузили из FB sdk? –