openActiveSession为Facebook iOS SDK后过期访问令牌 [英] Expired access token after openActiveSession for Facebook iOS SDK
问题描述
这个执行完美无缺:
[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession * fbSession,FBSessionState fbState,NSError * error){...}
但是,当我尝试获取'我'信息时,我收到一个错误:
com.facebook.sdk:ParsedJSONResponseKey = {
body = {
error = {
code = 190;
error_subcode= 463;
message =验证访问令牌时出错:会话已在unix时间1348704000过期。当前unix时间为1348706984。
type = OAuthException;
};
};
code = 400;
}
如果我看看 [错误代码] code>它等于5.我刚刚登录后不应该有一个有效的访问令牌?我需要重新授权吗?
更新:重新授权不会有帮助。奇怪的是,我的activeSession的accessToken总是回来一样。这个尽管调用了closeAndClearToken。
更新
这个问题已在Facebook iOS SDK 3.1.1中解决。
我同步了github的代码并发现他们没有在任何地方调用 accountStore renewCredentialsForAccount:completion:
。我更改了 authorizeUsingSystemAccountStore
中的以下代码,似乎已经解决了这个问题。
//我们将尝试iOS集成的facebook登录
[accountStore requestAccessToAccountsWithType:accountType
options:options
completed:^(BOOL approved,NSError * error){
//这意味着用户还没有通过操作系统登录到Facebook上
BOOL isUntosedDevice =(!approved&& error.code == ACErrorAccountNotFound);
dispatch_block_t postReauthorizeBlock = ^ {
NSString * oauthToken = nil;
if(approved){
NSArray * fbAccounts = [accountStore accountsWithAccountType:accountType];
id account = [fbAccounts objectAtIndex:0];
id credential = [account credential];
oauthToken = [credential oauthToken];
}
//初始验证案例
如果(!isReauthorize){
if(oauthToken){
_isFacebookLoginToken = YES;
_isOSIntegratedFacebookLoginToken = YES;
//我们刚刚收到一个令牌
self.refreshDate = [NSDate date];
//设置标记和日期,状态转换,并调用处理程序如果有一个
[self transitionAndCallHandlerWithState:FBSessionStateOpen
error:nil
token:oauthToken
// BUG:我们需要一种方法来获取令牌的到期日期
expirationDate:[NSDate distantFuture]
shouldCache:YES
loginType:FBSessionLoginTypeSystemAccount];
} else if(isUntosedDevice){
//即使OS集成auth是可能的,我们使用native-app / safari
//如果用户尚未通过操作系统登录到Facebook,则登录
[self authorizeWithPermissions:permissions
defaultAudience:defaultAudience
integratedAuth:NO
FBAppAuth:YES
safariAuth:YES
fallback:YES
isReauthorize:没有];
} else {
//创建一个关于失败登录的附加信息的错误对象
NSError * err = [FBSession errorLoginFailedWithReason:nil
errorCode:nil
innerError:error ]。
//状态转换,如果有一个
,则调用处理程序[self transitionAndCallHandlerWithState:FBSessionStateClosedLoginFailed
error:err
token:nil
expirationDate: nil
shouldCache:NO
loginType:FBSessionLoginTypeNone];
}
} else {// reauth case
if(oauthToken){
//将请求的权限与已授予的权限相结合
NSMutableSet * set = [NSMutableSet setWithArray:self.permissions];
[set addObjectsFromArray:permissions];
//完成操作:success
[self completeReauthorizeWithAccessToken:oauthToken
expirationDate:[NSDate distantFuture]
权限:[set allObjects]];
} else {
//在这种情况下没有令牌意味着用户取消了权限升级
NSError * error = [FBSession errorLoginFailedWithReason:FBErrorReauthorizeFailedReasonUserCancelled
errorCode:nil
innerError:无];
//完成操作:失败
[self callReauthorizeHandlerAndClearState:error];
//如果我们使用一个未被设置的设备将其设置为reauth,那么
//现在是时间使会话无效
if(isUntosedDevice){
[self closeAndClearTokenInformation];
}
}
}
};
如果(已授权){
[accountStore renewCredentialsForAccount:[[accountStore accountsWithAccountType:accountType] lastObject] completion:^(ACAccountCredentialRenewResult renewResult,NSError * error){
dispatch_async(dispatch_get_main_queue(),postReauthorizeBlock);
}];
} else {
// requestAccessToAccountsWithType:options:completion:completed on a
//任意线程;让我们在我们的主线程
dispatch_async(dispatch_get_main_queue(),postReauthorizeBlock)处理这个;
}
}];
}
I'm using the 3.1 Facebook SDK with iOS 6 Facebook set up in Settings and my app authorized.
This executes flawlessly:
[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *fbSession, FBSessionState fbState, NSError *error) { ... }
However now when I try to get 'me' information I'm getting an 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;
}
If I look at [error code]
it's equal to 5. Shouldn't I have a valid access token after just logging in? Do I need to call reauthorize?
UPDATE: Reauthorizing doesn't help. Oddly the accessToken for my activeSession is always coming back the same. This despite calling closeAndClearToken.
UPDATE: This issue has been addressed in Facebook iOS SDK 3.1.1.
I synched the code off of github and found that they weren't calling accountStore renewCredentialsForAccount:completion:
anywhere. I changed the following code in authorizeUsingSystemAccountStore
and it seems to have resolved the issue.
// 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);
}
}];
}
这篇关于openActiveSession为Facebook iOS SDK后过期访问令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!