如何在使用Facebook iPhone SDK时刷新oauth标记

我在我的应用程序中使用iOS的Facebook SDK: http : //github.com/facebook/facebook-ios-sdk

oAuth令牌在约2小时后过期。 我怎样才能“刷新”oAuth令牌,而不必再次调用[Facebook授权…]方法 – 如果用户以前login过,会简要地显示一个空的Facebook对话框? 我想要避免的是要求用户每次使用应用程序时重新login到FB – 比如每天。

当应用程序退出/启动时,我已经保存/恢复oAuth令牌。 我可以使用[Facebook isSessionValid]来检查令牌是否有效,或者通过检查令牌的过期时间。 但是如果令牌已经过期怎么办? 我读过可以“刷新”令牌,但我不明白这是如何完成的。

我不想要求“offline_access”权限,这会给我一个“永远”的标记。

帮帮我!?

Facebook的OAuth实现不支持令牌刷新。

在Facebook中你有两种types的access_tokens。 短期令牌,默认情况下是给定的,如果您请求offline_access,则给出长期令牌。 如果支持刷新标记,则与为所有应用程序提供offline_access标记相同。

只要用户在你的网页控制器上有一个活跃的Facebook会话,你可以通过访问https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=http://www.facebook来申请一个新的access_token 。 com / connect / login_success.html&response_type = token或者可能是一些相同的iOS SDK命令(从来没有使用过,所以我不能告诉)。 这种请求不会要求用户再次login,而是使用先前在第一次login时创build的会话。

由于这些答案都没有真正解决这个问题,所以我将详细介绍如何使用Facebook SDK实现OAuth令牌刷新。

当您发出请求时,SDK会自动刷新您的令牌,但是在我的场景中,我们会将令牌发送给我们的服务器,并且需要使用最新的令牌。 所以当我们的服务器指出我们需要新的令牌时,我们就是这么做的:

注意您可以将AppID传递到FBSession或者您可以将FacebookAppID键添加到您的应用程序的plist(这是我们所做的)。

 - (void)renewFacebookCredentials { if (FBSession.activeSession.state == FBSessionStateOpen || FBSession.activeSession.state == FBSessionStateOpenTokenExtended) { [self sessionStateChanged:[FBSession activeSession] state:[FBSession activeSession].state error:nil]; } else { // Open a session showing the user the login UI // You must ALWAYS ask for public_profile permissions when opening a session [FBSession openActiveSessionWithReadPermissions:@[@"public_profile",@"email"] allowLoginUI:NO completionHandler:^(FBSession *session, FBSessionState state, NSError *error) { //this block will run throughout the lifetime of the app. [self sessionStateChanged:session state:state error:error]; }]; } } 

您可以使用Facebook在其文档中包含的sessionStateChanged:方法,但简化的处理程序如下所示:

 - (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error { // If the session was opened successfully NSString *accessToken; if (!error && state == FBSessionStateOpen && [[session accessTokenData] accessToken]){ // Show the user the logged-in UI //@see http://stackoverflow.com/questions/20623728/getting-username-and-profile-picture-from-facebook-ios-7 accessToken = [[session accessTokenData] accessToken]; //Now we have an access token, can send this to the server... } else { //No access token, show a dialog or something } //either call a delegate or a completion handler here with the accessToken } 

请注意,一些FBSession API调用检查线程亲和力,所以我发现我不得不将所有的FBSession调用包装在dispatch_async(dispatch_get_main_queue(), ^{...

只要做[[FBSession会话]恢复]如果它返回false再次login

Facebook iOS SDK不处理会话存储。 FBSessionDelegate是你的应用程序应该实现的callback接口。 它的方法将被调用应用程序的成功login或注销。

有关fbDidLoginfbDidNotLoginfbDidLogout方法,请参阅示例应用程序facebook-ios-sdk/sample/DemoApp/Classes/DemoAppViewController.m

根据Facebook SDK文档:

如有必要,Facebook SDK会自动刷新用户的会话。 当它这样做时,状态也转换到FBSessionStateOpenTokenExtended状态。

还要进一步澄清(自SDK 3.1以来):

SDK会在API调用中自动刷新会话。

当使用SDK进行后续authentication或Facebook API调用时,它还根据需要刷新令牌数据。