0
votes

So I've just recently started working with iOS development and am using the PodioKit library to interface with Podio. After authenticating with the server using an email and password, it returns an OAuth token. This has the required data, refresh token, etc.

To keep the user logged in between uses of the app, the OAuth token is supposed to get saved to the keychain, then accessed again on app startup. I've been using JNKeychain to store them in the keychain, and that seems to be working okay. However, when I retrieve the token from the keychain, the data is not the same, meaning that PodioKit throws a "Refresh token missing" error any time I try to do anything. You can see the difference in these NSLog outputs.

Before saving to Keychain:

2014-01-23 15:40:38.069 PodioKPITest[377:60b] oauthToken: <PKOAuth2Token: 0x16d59390>
2014-01-23 15:40:38.071 PodioKPITest[377:60b] oauthToken.refData: {
    id = 1883826;
    type = user;
}
2014-01-23 15:40:38.072 PodioKPITest[377:60b] oauthToken.refreshToken: d9a59577e0574d20bdbc739ccfcf61ce
2014-01-23 15:40:38.073 PodioKPITest[377:60b] oauthToken.accessToken: 53909cabac874fb78fcca7eda87a4e84
2014-01-23 15:40:38.079 PodioKPITest[377:60b] oauthToken.expiresOn: 2014-01-23 12:40:38 +0000
2014-01-23 15:40:38.080 PodioKPITest[377:60b] oauthToken.transferToken: (null)

After loading from Keychain:

2014-01-23 15:41:00.509 PodioKPITest[389:60b] oauthToken: <PKOAuth2Token: 0x14d42cb0>
2014-01-23 15:41:00.512 PodioKPITest[389:60b] oauthToken.refData: (null)
2014-01-23 15:41:00.514 PodioKPITest[389:60b] oauthToken.refreshToken: (null)
2014-01-23 15:41:00.516 PodioKPITest[389:60b] oauthToken.accessToken: (null)
2014-01-23 15:41:00.521 PodioKPITest[389:60b] oauthToken.expiresOn: 2014-01-23 04:40:38 +0000
2014-01-23 15:41:00.523 PodioKPITest[389:60b] oauthToken.transferToken: (null)

Does anyone have any idea why this is happening? Is there a better/more correct place to be storing a token than in the Keychain? Hopefully I've explained myself okay!

1

1 Answers

0
votes

Yes, the keychain is the right place to store the token since it will be encrypted.

I tried the exact same thing you did with Podio and JNKeychain and for me it did work. Which version of PodioKit and JNKeychain are you using? it seems the the unarchiving fails to restore those property values in your case.

PKOAuth2Token *token = [[PKOAuth2Token alloc] initWithAccessToken:@"access1234"
                                                     refreshToken:@"refresh1234"
                                                    transferToken:@"transfer1234"
                                                        expiresOn:[NSDate dateWithTimeIntervalSinceNow:3600]
                                                          refData:@{@"ref": @"somedata"}];

// Test archiving
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:token];
PKOAuth2Token *archivedToken = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"Restored access token from archive %@", archivedToken.accessToken);

// Test keychain
NSString *keychainKey = @"AuthToken";
[JNKeychain saveValue:token forKey:keychainKey];
PKOAuth2Token *keychainToken = [JNKeychain loadValueForKey:keychainKey];
NSLog(@"Restored access token from keychain: %@", keychainToken.accessToken);

The above prints:

2014-01-23 21:07:22.719 App[17202:70b] Restored access token from archive access1234
2014-01-23 21:07:22.723 App[17202:70b] Restored access token from keychain: access1234

You could always try an alternative keychain wrapper library, like FXKeychain.