适用于iOS的Box.com SDK:检查授权状态

时间:2013-07-21 20:11:51

标签: ios box-api

适用于iOS的box.com SDK有一个名为sharedSDK的对象,其中包含另一个名为OAuth2Session的对象。 OAuth2Session有一个名为isAuthorized的属性。在每个应用程序启动时,此属性设置为NO。即使我将refreshToken保留在系统Keychain中,并在启动时分配它,如下所示:

//...applicationDidFinisLaunching...
NSString *token = [controllerObject fetchFromKeychainForKey:@"com.box.token"];
[BoxSDK sharedSDK].OAuth2Session.refreshToken = token;

if ([BoxSDK sharedSDK].OAuth2Session.isAuthorized) {
    //Not until signing in
    NSLog(@"Authorized.)";
} else {
    NSLog(@"Not Authorized.");
}

我应该做些什么来检查身份验证状态? Dropbox SDK有一种方法可以确定会话是否已链接,并通过启动持续存在。

1 个答案:

答案 0 :(得分:3)

我是iOS SDK的作者。 isAuthorized方法只是对当前OAuth2令牌是否有效的最佳猜测。来自documentation

  

将accessTokenExpiration与当前时间进行比较,以确定访问令牌是否有效。这并不能保证访问令牌有效,因为它可能已被撤销或已刷新。

由于Box iOS SDK没有存储accessTokenExpiration,因此即使加载了刷新令牌,此字段也会在初始化后为零。

Box iOS SDK采取的态度是Box API是关于状态的真相来源,并且不会尝试执行服务器可以更可靠地处理的客户端检查。

重新加载OAuth2会话的推荐方法是按照您的方式设置钥匙串中的刷新令牌,然后发出“心跳”API调用以在刷新令牌无效时触发自动刷新或失败。

可以在Box iOS SDK sample app

中找到此示例
- (void)viewDidLoad
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(boxAPIAuthenticationDidSucceed:)
                                                 name:BoxOAuth2SessionDidBecomeAuthenticatedNotification
                                               object:[BoxSDK sharedSDK].OAuth2Session];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(boxAPIAuthenticationDidFail:)
                                                 name:BoxOAuth2SessionDidReceiveAuthenticationErrorNotification
                                               object:[BoxSDK sharedSDK].OAuth2Session];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(boxAPIInitiateLogin:)
                                                 name:BoxOAuth2SessionDidReceiveRefreshErrorNotification
                                               object:[BoxSDK sharedSDK].OAuth2Session];

    // attempt to heartbeat. This will succeed if we successfully refresh
    // on failure, the BoxOAuth2SessionDidReceiveRefreshErrorNotification notification will be triggered
    [self boxAPIHeartbeat];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)boxAPIHeartbeat
{
    [[BoxSDK sharedSDK].foldersManager folderInfoWithID:BoxAPIFolderIDRoot requestBuilder:nil success:nil failure:nil];
}

#pragma mark - Handle OAuth2 session notifications
- (void)boxAPIAuthenticationDidSucceed:(NSNotification *)notification
{
    NSLog(@"Received OAuth2 successfully authenticated notification");
    BoxOAuth2Session *session = (BoxOAuth2Session *) [notification object];
    NSLog(@"Access token  (%@) expires at %@", session.accessToken, session.accessTokenExpiration);
    NSLog(@"Refresh token (%@)", session.refreshToken);

    [self dismissViewControllerAnimated:YES completion:nil];

    BOXAssert(self.viewControllers.count == 1, @"There should only be one folder in the hierarchy when authentication succeeds");
    BoxFolderViewController *rootVC = (BoxFolderViewController *)self.topViewController;
    [rootVC fetchFolderItemsWithFolderID:BoxAPIFolderIDRoot name:@"All Files"];
}

- (void)boxAPIAuthenticationDidFail:(NSNotification *)notification
{
    NSLog(@"Received OAuth2 failed authenticated notification");
    NSString *oauth2Error = [[notification userInfo] valueForKey:BoxOAuth2AuthenticationErrorKey];
    NSLog(@"Authentication error  (%@)", oauth2Error);

    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)boxAPIInitiateLogin:(NSNotification *)notification
{
    NSLog(@"Refresh failed. User is logged out. Initiate login flow");

    dispatch_sync(dispatch_get_main_queue(), ^{
        [self popToRootViewControllerAnimated:YES];

        NSURL *authorizationURL = [BoxSDK sharedSDK].OAuth2Session.authorizeURL;
        NSString *redirectURI = [BoxSDK sharedSDK].OAuth2Session.redirectURIString;
        BoxAuthorizationViewController *authorizationViewController = [[BoxAuthorizationViewController alloc] initWithAuthorizationURL:authorizationURL redirectURI:redirectURI];
        BoxAuthorizationNavigationController *loginNavigation = [[BoxAuthorizationNavigationController alloc] initWithRootViewController:authorizationViewController];
        authorizationViewController.delegate = loginNavigation;
        loginNavigation.modalPresentationStyle = UIModalPresentationFormSheet;

        [self presentViewController:loginNavigation animated:YES completion:nil];
    });

}

此视图控制器注册OAuth2通知,这些通知在成功刷新或注销时触发。在注册这些回调的选择器中,您可以在应用程序中加载视图控制器或加载BoxAuthorizationViewController以记录用户。