【问题标题】:Does the Facebook iOS SDK require the user to authenticate every time they use the app?Facebook iOS SDK 是否要求用户在每次使用应用程序时进行身份验证?
【发布时间】:2011-07-31 02:36:53
【问题描述】:

如 facebook-ios-sdk 的自述文件中所述,我的应用在执行任何 API 调用之前调用 Facebook#authorize:delegate:。

此方法要求用户进行身份验证(在 Facebook 应用程序或 Safari 中),然后将控制权交还给我的 iPhone 应用程序。问题是每次我调用该方法时它都会要求用户进行身份验证。如果他们已经授予了我的应用程序的权限,他们会收到一条消息,说明该应用程序已获得授权,他们必须按“确定”才能返回我的应用程序。看起来不是很专业。

所以我有两个问题:

  1. 用户是否总是必须重新授权才能拨打 Facebook 电话?我一直认为它会将访问令牌保存在某处,可能在用户默认值中,这样您就不需要重新授权。

  2. 如果用户不必每次都重新授权,有没有办法检查我的应用程序是否已经获得权限,这样用户就不必看到该消息并按确定?

【问题讨论】:

  • 您必须自己保存 accessToken 和 expirationDate。检查我的代码答案。

标签: ios facebook facebook-ios-sdk


【解决方案1】:

很遗憾,Facebook SDK 没有自动为我们处理它。除了自己构建到 SDK 之外,最简单的方法是:

每次分配_facebook:

_facebook = [[Facebook alloc] initWithAppId:@"SuperDuperAppID"];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *accessToken = [prefs stringForKey:@"facebook-accessToken"];
NSString *expirationDate = [prefs stringForKey:@"facebook-expirationDate"];
_facebook.accessToken = accessToken;
_facebook.expirationDate = expirationDate;

如果您从未在 NSUserDefaults 中保存过任何内容,则将设置 nil 值。什么都没发生。否则,将设置真值,[_facebook isSessionValid]; 应返回 TRUE,表示值良好。继续进行 Facebook SDK 调用,就好像它们已登录(它们是)一样。如果为假,则调用

[facebook authorize:permissions delegate:self]; 

像往常一样。

然后确保支持以下 Facebook 委托方法:

- (void)fbDidLogin {
NSString *accessToken = _facebook.accessToken;
NSString *expirationDate = _facebook.expirationDate;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:accessToken forKey:@"facebook-accessToken"];
[prefs expirationDate forKey:@"facebook-expirationDate"];
[prefs synchronize];
}

我在我的应用程序中使用此代码,它运行良好。我是凭记忆做到的,所以如果它不适用于复制和粘贴,我深表歉意。某处可能存在输入错误,以及内存管理不当。不要忘记访问令牌会过期,除非您获得离线许可。无论如何,上面的代码可以处理所有事情。

【讨论】:

  • 谢谢,丹尼尔。我读过默认的到期日期是从登录后只有 24 小时。这是你的经历吗?
  • 确实,24 小时,但我几乎总是要求“offline_access”权限,这授予它无限的终身有效性(禁止用户手动拒绝权限)。
  • 我明白了。我只需要为 photos.upload 操作登录。如果我请求 offline_access 并存储令牌,那会起作用吗?我认为offline_access 严格用于只读数据,但我可能错了。
  • 是的,offline_access 主要是只读的。 publish_stream 是写权限。
  • 你第一个sn-p的最后一行打错了expirationData --> expirationDate
【解决方案2】:

问题是它要求用户 每次我打电话时都进行身份验证 方法。如果他们已经授予 我的应用程序的许可,他们得到一个 消息说该应用程序已经 授权,他们必须按 OK 回到我的应用程序。

1) 用户是否总是必须 重新授权以使 Facebook 电话?我一直以为会省钱 某处的访问令牌,可能在 用户默认,让你 不需要重新授权。

每次都必须经过登录过程的原因是,在第一次成功登录后,Facebook SDK 没有持久保存访问令牌

2) 如果用户不需要 每次都重新授权,有没有办法 检查我的应用是否已经有 权限,所以用户没有 要查看该消息并按确定?

Facebook SDK 不保存访问令牌这一事实并不意味着您不能自己做。以下代码说明了如何从 NSUserDefaults 保存/检索访问令牌。

-(void)login {
    // on login, use the stored access token and see if it still works
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    facebook.accessToken = [defaults objectForKey:ACCESS_TOKEN_KEY];
    facebook.expirationDate = [defaults objectForKey:EXPIRATION_DATE_KEY];

    // only authorize if the access token isn't valid
    // if it *is* valid, no need to authenticate. just move on
    if (![facebook isSessionValid]) {
        NSArray * permissions = [NSArray arrayWithObjects:@"read_stream", @"offline_access", @"email", nil];
        [facebook authorize:permissions delegate:self];
    }
}

/**
 * Called when the user has logged in successfully.
 */
- (void)fbDidLogin {
    // store the access token and expiration date to the user defaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:facebook.accessToken forKey:ACCESS_TOKEN_KEY];
    [defaults setObject:facebook.expirationDate forKey:EXPIRATION_DATE_KEY];
    [defaults synchronize];
}

【讨论】:

  • @albertamg 这正是我的做法,一切都很好,但我有一个问题是,因为 facebook 使用单点登录,这意味着如果我登录到我的 facebook我的iphone上的应用程序,我不必在其他应用程序中再次登录,对吗?但是该应用程序只能在 fbDIdLogin 方法中保存访问令牌和到期日期,并且只有在用户在登录页面上输入他的凭据后才会调用该方法,理想情况下用户不需要输入他的凭据,甚至他也不应该看到登录页面,他第一次看到的只是“允许访问此应用”屏幕
  • @yogesh 这里发生了两件事:用户登录和用户授权您的应用程序。正如您所说,Facebook 使用单点登录(至少是 sdk 的更新版本)。如果用户已经登录(在设备上),他/她仍然必须授权您的应用程序(如果他/她还没有这样做)。因此,如果用户没有登录,他将被重定向到登录页面,然后到授权页面。如果用户已经登录,他将被直接重定向到授权页面。
  • @albertamg 感谢您的回复,所以这就是正在发生的事情,当用户第一次来到我的应用程序时,他看到了一个登录屏幕,他必须输入他的凭据,我想这应该不会发生,因为他已经在手机上登录了 Facebook 应用程序,但是是的,他必须授权该应用程序,这很好,困扰我的是为什么他必须登录,即使他已登录到 facebook 应用程序
  • @yogesh 这不会发生在我身上。我的经验如下。如果用户在他/她第一次运行我的应用程序时登录到 facebook 应用程序,他/她将被直接重定向到授权页面(第一次您无法避免)。但是,如果用户没有登录到 facebook 应用程序(或更一般地,在设备上),他/她将被重定向到登录页面,然后到授权页面。如果他/她通过我的应用程序登录后访问 facebook 应用程序,则他/她已登录。
  • @yogesh 我什么都看不到。我建议您阅读 facebook SDK 页面 (github.com/facebook/facebook-ios-sdk) 的“单点登录”部分,该部分描述了不同版本的 sdk 如何执行授权,具体取决于是否安装了 facebook 应用程序及其设备支持多任务处理与否。
【解决方案3】:

当用户登录时,您将获得一个访问令牌和一个到期日期。保存访问令牌,只要您还没有达到到期日期,就可以重复使用它。 Facebook SDK 有一个方法来做这个检查:[fbConnect isSessionValid] 但它似乎有时会给出误报,所以如果请求失败,我会让用户登录。

【讨论】:

    【解决方案4】:

    1) 不,我必须使用Facebook *fbConnect = [[Facebook alloc] init]; [fbConnect logout:self]; 才能取消用户会话

    2) 我想你可以调用 Facebook.m 中的 accestoken 来检查

    【讨论】:

      【解决方案5】:

      这是@Daniel Amitay 答案的更实际方法:
      在带有登录按钮的视图控制器中编写

      //saving user data to user defaults in order to support Facebook SSO
      let token = FBSDKAccessToken.currentAccessToken()
      let prefs = NSUserDefaults.standardUserDefaults()
      let nsdataToken = NSKeyedArchiver.archivedDataWithRootObject(token)
      prefs.setObject(nsdataToken, forKey: "facebook-AccessToken")
      prefs.synchronize()
      

      在 AppDelegate 文件中func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 你写如下

      //restoring Facebook SSO session from user defaults
      let prefs = NSUserDefaults.standardUserDefaults()
      if let nsdataToken = prefs.valueForKey("facebook-AccessToken") as? NSData {
          let token = NSKeyedUnarchiver.unarchiveObjectWithData(nsdataToken) as! FBSDKAccessToken
          FBSDKAccessToken.setCurrentAccessToken(token)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-19
        • 2019-02-02
        相关资源
        最近更新 更多