我正在使用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();
}
}
答案 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;
}
}
}
}