2012-09-27 103 views
9

我正在使用設置和我的應用程序授權的iOS 6 Facebook設置3.1 Facebook SDK。但是現在在Facebook iOS SDK的openActiveSession之後過期的訪問令牌

[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *fbSession, FBSessionState fbState, NSError *error) { ... } 

,當我試圖讓「我」的信息,我發現了一個錯誤:

這完美地執行

com.facebook.sdk:ParsedJSONResponseKey = { 
    body =  { 
     error =   { 
      code = 190; 
      "error_subcode" = 463; 
      message = "Error validating access token: Session has expired at unix time 1348704000. The current unix time is 1348706984."; 
      type = OAuthException; 
     }; 
    }; 
    code = 400; 
} 

如果我看[error code]它等於5。在登錄後不應該有一個有效的訪問令牌嗎?我需要重新授權嗎?

UPDATE:重新授權不起作用。奇怪的是我的activeSession的accessToken總是回來一樣。這儘管調用closeAndClearToken。

+2

要開始診斷,您可以記錄您獲得的access_token並將其粘貼到https://developers.facebook.com/tools/debug - 時間戳記是否在那裏? –

+0

好的提示。現在問題消失了,我需要重新創建它。我會在下次看到它時嘗試你的建議。 –

+0

我與iPhone5/iOS6有同樣的問題。雖然這看起來很零星。如果您發現有關此問題的更多信息,請讓我知道,我也會這樣做。 – Chad

回答

4

UPDATE: 此問題已在Facebook的iOS版SDK 3.1.1得到解決。


我同步的代碼關閉github上,發現他們並沒有打電話accountStore renewCredentialsForAccount:completion:任何地方。我在authorizeUsingSystemAccountStore中更改了下面的代碼,它似乎解決了這個問題。

// we will attempt an iOS integrated facebook login 
[accountStore requestAccessToAccountsWithType:accountType 
             options:options 
            completion:^(BOOL granted, NSError *error) { 

             // this means the user has not signed-on to Facebook via the OS 
             BOOL isUntosedDevice = (!granted && error.code == ACErrorAccountNotFound); 

             dispatch_block_t postReauthorizeBlock = ^{ 
              NSString *oauthToken = nil; 
              if (granted) {                          
               NSArray *fbAccounts = [accountStore accountsWithAccountType:accountType]; 
               id account = [fbAccounts objectAtIndex:0]; 
               id credential = [account credential];             
               oauthToken = [credential oauthToken]; 
              } 

              // initial auth case 
              if (!isReauthorize) { 
               if (oauthToken) { 
                _isFacebookLoginToken = YES; 
                _isOSIntegratedFacebookLoginToken = YES; 

                // we received a token just now 
                self.refreshDate = [NSDate date]; 

                // set token and date, state transition, and call the handler if there is one 
                [self transitionAndCallHandlerWithState:FBSessionStateOpen 
                        error:nil 
                        token:oauthToken 
                // BUG: we need a means for fetching the expiration date of the token 
                      expirationDate:[NSDate distantFuture] 
                       shouldCache:YES 
                       loginType:FBSessionLoginTypeSystemAccount]; 
               } else if (isUntosedDevice) { 
                // even when OS integrated auth is possible we use native-app/safari 
                // login if the user has not signed on to Facebook via the OS 
                [self authorizeWithPermissions:permissions 
                    defaultAudience:defaultAudience 
                    integratedAuth:NO 
                     FBAppAuth:YES 
                     safariAuth:YES 
                     fallback:YES 
                    isReauthorize:NO]; 
               } else { 
                // create an error object with additional info regarding failed login 
                NSError *err = [FBSession errorLoginFailedWithReason:nil 
                           errorCode:nil 
                          innerError:error]; 

                // state transition, and call the handler if there is one 
                [self transitionAndCallHandlerWithState:FBSessionStateClosedLoginFailed 
                        error:err 
                        token:nil 
                      expirationDate:nil 
                       shouldCache:NO 
                       loginType:FBSessionLoginTypeNone]; 
               } 
              } else { // reauth case 
               if (oauthToken) { 
                // union the requested permissions with the already granted permissions 
                NSMutableSet *set = [NSMutableSet setWithArray:self.permissions]; 
                [set addObjectsFromArray:permissions]; 

                // complete the operation: success 
                [self completeReauthorizeWithAccessToken:oauthToken 
                      expirationDate:[NSDate distantFuture] 
                       permissions:[set allObjects]]; 
               } else { 
                // no token in this case implies that the user cancelled the permissions upgrade 
                NSError *error = [FBSession errorLoginFailedWithReason:FBErrorReauthorizeFailedReasonUserCancelled 
                           errorCode:nil 
                           innerError:nil]; 
                // complete the operation: failed 
                [self callReauthorizeHandlerAndClearState:error]; 

                // if we made it this far into the reauth case with an untosed device, then 
                // it is time to invalidate the session 
                if (isUntosedDevice) { 
                 [self closeAndClearTokenInformation]; 
                } 
               } 
              } 
             }; 



             if (granted) { 
              [accountStore renewCredentialsForAccount:[[accountStore accountsWithAccountType:accountType] lastObject] completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) { 
               dispatch_async(dispatch_get_main_queue(), postReauthorizeBlock); 
              }]; 
             } else { 
              // requestAccessToAccountsWithType:options:completion: completes on an 
              // arbitrary thread; let's process this back on our main thread 
              dispatch_async(dispatch_get_main_queue(), postReauthorizeBlock); 
             } 

            }]; 

} 
+0

我們應該在更新之前檢查expiryDate(因爲它需要時間來更新),但儘管它在Apple的文檔中說了什麼(http://developer.apple.com/library/ios/#documentation/Accounts/Reference/ACAccountCredentialClassRef /Reference/Reference.html#//apple_ref/doc/c_ref/ACAccountCredential),expiryDate參數似乎不存在。 –

+2

嗨本,你說的需要致電續訂*。從這裏打電話很好。在哪裏進行呼叫的選擇通常取決於行爲一致性和額外的網絡往返之間的折衷。在下一次SDK更新中,我們正考慮在處理無效令牌的FBRequestConnection邏輯中進行調用。 –

+0

@JasonClark這似乎是一個合理的選擇。我建議在FB SDK中只有一個普通的舊的更新電話。如果您只是使用SDK進行令牌管理,而不是用於進行圖形調用的管道,那將很有用。感謝您的迴應! –

0

所以這個問題已經解決了,但是我從後臺調用/ me來驗證,因爲你不能相信這個設備。

所以我打電話給FBSession+ (void)renewSystemAuthorization當後端回來帶有授權錯誤。

+1

我在3.1.1的FBSession中看不到renewSystemAuthorization類的方法。 – gerry3

+0

看起來他們是按照這個承諾解決了這個問題。 https://github.com/facebook/facebook-ios-sdk/commit/0b3d28b7bea8b63dd9efca67e1438d72fc78daf5 – hawflakes