Windows phone 8 facebooksdk登录并重新登录

时间:2014-10-02 11:40:37

标签: c# facebook windows-phone-8 facebook-c#-sdk

我正在使用Windows Phone 8应用程序,我想将facebook登录集成到应用程序中。我下载了Facebook和Facebook.Client nuget包。

我按照本教程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 个答案:

答案 0 :(得分: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;
            }
        }
    }
}