[X] This issue is not security related and can safely be disclosed publicly on GitHub
Xcode version
15.2
Facebook iOS SDK version
17.0.1
Dependency Manager
Prebuilt Binaries
SDK Framework
Login
Goals
I want to use FBSDKAuthenticationToken.currentAuthenticationToken when the user opens the application, this user has logged-in with the limited log-in in a previous session and I'd like to use his authentication token.
Expected results
To get a non-nil FBSDKAuthenticationToken.currentAuthenticationToken whenever it is called, it happens after the set-up of the facebook-ios-sdk, the facebook-ios-sdk should be useable at that time.
Actual results
In reality FBSDKAuthenticationToken.currentAuthenticationToken is nil when I first access it, I get the non-nil valid value only with a retry mechanism. With solid internet connection I get the non-nil auth token only after 0.4 seconds after the first call to the the method approximately.
The main issue is I don't know when the user is actually logged-out and when the authentication token in nil because of this delay, if the user logs-out via facebook's side I'll just run my retry mechanism until I reach time out.
It is worth noting that the exact same issue occurs with FBSDKAccessToken.currentAccessToken in the non-limited regular log-in. When I used version 12.3.1 of the sdk I got the valid non-nil value as soon as I accessed it, now I get the same delay there.
The currentAuthenticationToken isn't well documented, it isn't clear when it should be nil or not, it feels like there was a behavior change under the hood.
Bottom line, please explain when and why the authentication token is nil, when should I decide that the user is actually logged-out and when I need to wait/retry, an even better solution is to ensure that the FBSDKAuthenticationToken.currentAuthenticationToken and FBSDKAccessToken.currentAccessToken are accessible as soon as possible whenever they have a value, otherwise doc them to explain how they should be used.
Thanks!
Steps to reproduce
Successfully log-in with the limited facebook log-in.
Close the application.
Re-open it, the first access to FBSDKAuthenticationToken.currentAuthenticationToken is nil even though the user should be logged-in.
Code samples & details
// The code the does the facebook log-in
- (void)loginWithPresentingViewController:(UIViewController *)presentingViewController
block:(void(^)(NSString * _Nullable token, BOOL cancelled,
NSError * _Nullable error))block {
auto configuration =
[[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"]
tracking:FBSDKLoginTrackingLimited];
dispatch_async(dispatch_get_main_queue(), ^{
[self.loginManager logInFromViewController:presentingViewController
configuration:configuration
completion:^(FBSDKLoginManagerLoginResult * _Nullable result,
NSError * _Nullable error) {
if (!result || result.isCancelled) {
block(nil, result.isCancelled ?: NO, error);
return;
}
if (![self.loginPermissions isSubsetOfSet:nn(result.grantedPermissions)]) {
block(nil, NO, [NSError lt_errorWithCode:FORErrorCodeLoginFailed description:@"An error occured");
return;
}
block(nn(result.authenticationToken.tokenString), NO, nil);
}];
});
}
// The code that returns a `nil` authentication token.
- (void)loginStatusWithBlock:(void(^)(FORLoginSourceLoginStatus *tokenStatus,
NSString * _Nullable token, NSError * _Nullable error))block {
auto _Nullable currentAuthenticationToken = FBSDKAuthenticationToken.currentAuthenticationToken; // Here I get `nil` even though the user has successfully logged-in in the previous session.
if (currentAuthenticationToken) {
auto loginStatus = currentAuthenticationToken.lt_isActive ?
$(FORLoginSourceLoginStatusLoggedIn) : $(FORLoginSourceLoginStatusLoginExpired);
block(loginStatus, nn(currentAuthenticationToken.tokenString), nil);
} else {
block($(FORLoginSourceLoginStatusNotLoggedIn), nil, nil);
}
}
// The code that enables getting the non-nil authentication token with the retry mechanism.
- (void)loginStatusWithBlock:(void(^)(FORLoginSourceLoginStatus *tokenStatus,
NSString * _Nullable token, NSError * _Nullable error))block {
__block uint attempt = 0;
dispatch_queue_t queue = dispatch_queue_create("some queue", DISPATCH_QUEUE_SERIAL);
__block void (^retryRetrieveFacebookAccessTokenBlock)(void) = [^{
/// Works only after a few retries, approximately 4 retries in my case.
auto _Nullable currentAuthenticationToken = FBSDKAuthenticationToken.currentAuthenticationToken;
if (currentAuthenticationToken) {
/// Here I parse the JWT token to check if the token is expired or not.
auto loginStatus = currentAuthenticationToken.lt_isActive ?
$(FORLoginSourceLoginStatusLoggedIn) : $(FORLoginSourceLoginStatusLoginExpired);
block(loginStatus, nn(currentAuthenticationToken.tokenString), nil);
} else if (attempt < FORFacebookLoginSource.kMaxRetrieveFacebookAccessTokenRetryCount) {
++attempt;
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC));
dispatch_after(delay, queue, retryRetrieveFacebookAccessTokenBlock);
} else {
block($(FORLoginSourceLoginStatusNotLoggedIn), nil, nil);
return;
}
} copy];
retryRetrieveFacebookAccessTokenBlock();
}
+ (uint)kMaxRetrieveFacebookAccessTokenRetryCount {
return 20;
}
Checklist before submitting a bug report
Xcode version
15.2
Facebook iOS SDK version
17.0.1
Dependency Manager
Prebuilt Binaries
SDK Framework
Login
Goals
I want to use
FBSDKAuthenticationToken.currentAuthenticationToken
when the user opens the application, this user has logged-in with the limited log-in in a previous session and I'd like to use his authentication token.Expected results
To get a non-nil
FBSDKAuthenticationToken.currentAuthenticationToken
whenever it is called, it happens after the set-up of the facebook-ios-sdk, the facebook-ios-sdk should be useable at that time.Actual results
In reality
FBSDKAuthenticationToken.currentAuthenticationToken
isnil
when I first access it, I get the non-nil valid value only with a retry mechanism. With solid internet connection I get the non-nil auth token only after 0.4 seconds after the first call to the the method approximately.The main issue is I don't know when the user is actually logged-out and when the authentication token in
nil
because of this delay, if the user logs-out via facebook's side I'll just run my retry mechanism until I reach time out.It is worth noting that the exact same issue occurs with
FBSDKAccessToken.currentAccessToken
in the non-limited regular log-in. When I used version 12.3.1 of the sdk I got the valid non-nil value as soon as I accessed it, now I get the same delay there.The
currentAuthenticationToken
isn't well documented, it isn't clear when it should benil
or not, it feels like there was a behavior change under the hood.Bottom line, please explain when and why the authentication token is
nil
, when should I decide that the user is actually logged-out and when I need to wait/retry, an even better solution is to ensure that theFBSDKAuthenticationToken.currentAuthenticationToken
andFBSDKAccessToken.currentAccessToken
are accessible as soon as possible whenever they have a value, otherwise doc them to explain how they should be used.Thanks!
Steps to reproduce
FBSDKAuthenticationToken.currentAuthenticationToken
isnil
even though the user should be logged-in.Code samples & details