我有一个可以有多个用户的 iOS 应用程序,我想将 Facebook 集成到其中。我想缓存每个用户的登录凭据。用户将有一个应用程序登录,因此每个用户将只能使用自己的 Facebook 信用。 Facebook 的文档指出,您可以通过在此处覆盖 FBSessionTokenCachingStrategy 对象来管理多个用户的 session token :
https://developers.facebook.com/docs/ios/login-tutorial/
我正在使用本地缓存方法,我在用户登录我的应用程序的地方使用它,然后如果他们有相关的 Facebook token ,我将他们登录到那里的 session 。否则,我会提示他们使用 Facebook 的 API 将用户重定向到 Facebook 网络登录页面,在那里输入 Facebook 凭据。
[FBSession openActiveSessionWithReadPermissions:@[@"basic_info"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error)
{
[self loginToFacebookEnd:session state:state error:error];
}];
上述方法对第一个用户非常有效。第二个登录的用户按预期被重定向到 Facebook 网络登录页面,但第一个用户现在通过 safari 登录,第二个用户现在使用第一个用户的凭据登录。
我希望能够不让用户在 safari 上保持登录状态,或者能够使用嵌入式 Web 对话框之类的东西。然而,根据 Facebook API 文档,嵌入式对话框似乎不允许我在应用程序重新启动后加载用户 token :
https://developers.facebook.com/docs/ios/login-tutorial/#control
"Embedded WebView Login Dialog Disadvantage: People have to fill in their login credentials every time they go through the login flow."
此外,当从嵌入式 WebView 保存 token 时,调用以下方法会清除我的 token 缓存:
FBSession *session = [[FBSession alloc] initWithAppID:nil
permissions:@[@"basic_info"]
urlSchemeSuffix:nil
tokenCacheStrategy:tokenCaching];
有谁知道如何支持多个用户从 iOS 应用程序登录 Facebook,而不会在 Safari 中缓存第一个用户的凭据?
更新 1
好的,我知道现在可以使用嵌入式 WebView 处理多个用户,因为 Facebook 包含在 SDK 中的示例程序之一 (SwitchUserSample) 可以做到这一点。加载我的 FBSession 似乎有问题,因为很多值都是空的,尽管我调用的代码与示例完全相同。有谁知道什么会导致 session 像这样恢复:
<FBSession: 0x16d9f3a0, state: FBSessionStateCreated, loginHandler: 0x0, appID: 658013034244859, urlSchemeSuffix: , tokenCachingStrategy:<FBSessionTokenCachingStrategy: 0x16d56190>, expirationDate: (null), refreshDate: (null), attemptedRefreshDate: 0001-12-30 00:00:00 +0000, permissions:(null)>
如果我使用 FBSessionLoginBehaviorForcingWebView 以外的任何行为,那么我会得到它作为我的反序列化 token :
<FBSession: 0x155823d0, state: FBSessionStateOpen, loginHandler: 0x73364, appID: 658013034244859, urlSchemeSuffix: , tokenCachingStrategy:<FBSessionTokenCachingStrategy: 0x15577c90>, expirationDate: 2014-02-15 20:01:50 +0000, refreshDate: 2013-12-17 20:01:51 +0000, attemptedRefreshDate: 0001-12-30 00:00:00 +0000, permissions:(
"user_birthday",
"user_friends"
)>
更新 2
我发现这肯定与我的 token 的缓存方式有关。我已经复制了 Facebook 示例正在使用的方法,但我仍然在 FBSession 中获取我的日期的空值。以下是我正在调用的缓存方法:
+ (FBSessionTokenCachingStrategy*)createCachingStrategyForSlot:(int)slot {
FBSessionTokenCachingStrategy *tokenCachingStrategy = [[FBSessionTokenCachingStrategy alloc]
initWithUserDefaultTokenInformationKeyName:[NSString stringWithFormat:@"SUUserTokenInfo%d", slot]];
return tokenCachingStrategy;
}
+ (FBSession*)createSessionForSlot:(int)slot {
FBSessionTokenCachingStrategy *tokenCachingStrategy = [self createCachingStrategyForSlot:slot];
FBSession *session = [[FBSession alloc] initWithAppID:nil
permissions:@[@"basic_info",@"user_birthday"]
urlSchemeSuffix:nil
tokenCacheStrategy:tokenCachingStrategy];
return session;
}
我是这样调用它的:
+ (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
BOOL openSessionResult = NO;
FBSession *session = [self createSessionForSlot:1];
// If showing the login UI, or if a cached token is available, then open the session.
if (allowLoginUI || session.state == FBSessionStateCreatedTokenLoaded)
{
// For debugging purposes log if cached token was found
if (session.state == FBSessionStateCreatedTokenLoaded)
{
NSLog(@"Cached token found.");
}
// Set the active session
[FBSession setActiveSession:session];
// If the session state is not any of the two "open" states when the button is clicked
if (FBSession.activeSession.state != FBSessionStateOpen && FBSession.activeSession.state != FBSessionStateOpenTokenExtended)
{
// Open the session.
[session openWithBehavior:FBSessionLoginBehaviorForcingWebView
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error)
{
[SocialInteraction loginToFacebookEnd:session state:state error:error];
}];
}
// Return the result - will be set to open immediately from the session
// open call if a cached token was previously found.
openSessionResult = session.isOpen;
}
return openSessionResult;
}
令人沮丧的是,如果我将登录行为从 FBSessionLoginBehaviorForcingWebView 更改为 FBSessionLoginBehaviorWithFallbackToWebView,那么 token 会正确加载!但是,此行为不适用于我的应用程序。必须有一些我遗漏的其他设置可以让嵌入式 WebView 缓存其 token 。
最佳答案
我将此从评论移至回答,以便我可以输入更多内容:
如果您的 FBSession
实例的状态是 FBSessionStateCreated
那么您将没有 expirationDate
属性等。根据我的经验,它必须有效打开(FBSessionStateCreatedTokenLoaded
、FBSessionStateOpen
、FBSessionStateOpenTokenExtended
)。您的 FBSession 对象是否有关联的 accessToken?如果是,则继续并尝试打开 session 并查看状态是否发生变化,并且您会在以前为 NULL 的地方获得值。
当我有一个有效的 accessToken
时打开 FBSession
我通常使用:
[FBSession openActiveSessionWithAllowLoginUI:NO];
更新 1:
好的,这是 Web View 的一种解决方法 - 如果您使用 Safari,则可以使用以下代码清除用户的 cookie。我可能会在 cookie 的域中搜索 Facebook.com
或 fb.com
(可能需要对 FB cookie 域是什么进行一些测试):
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies]) {
[storage deleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];
关于ios - 在 iOS 应用程序中处理多个 Facebook 用户登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20621642/