Reputation: 2140
Working on an iPhone app, I'm using the Google Plus SDK (GPPSignIn) for getting and refreshing authentication tokens.
These tokens last for 1 hour. When I make a request with an expired token the web service that I am using returns a specific http response code so that I know that my token has expired.
Upon receiving a response that my token has expired, I make a call to refresh the authentication token. Now I would like to repeat the request to the web service with the new token. And I'd like to do this all within my server request object.
If I was programming the whole works myself, I could just make the request for the token refreshing inline with the web server request and when token request is done, I could proceed with the web server request. But since the token work is done through Google Plus SDK, and they are using a delegate model for communicating the completion of the authentication request, I don't know how to hold the request to the web service until the token has been refreshed.
At present I'm trying out a "pretty bad" idea, which is shown below, where I attempt to put my request into a new thread and then put that thread to sleep for a while, at which point it wakes up and we hope that the new token is available. But there has to be a better way!
if (error !=nil && error.code == NSURLErrorUserCancelledAuthentication) {
//special handling of 401, which may be a Google Auth token failure.
// if it is, then let's go get a new token.
User *client = [[User alloc] init];
if(client.email != nil && client.password != nil){
if (client.accountType == AuthTypeGoogle) {
NSLog(@"attempt to get a new token");
// request new token
[client silentGoogleAuthentication];
//repeat request
if (repeatableRequest) {
dispatch_async(repeatQueue, ^{
[NSThread sleepForTimeInterval:4];
NSLog(@"sleepytime");
[self assignCredentialstoRequest];
[self makeRequest:notificationName repeatableRequest:false];
});
}
}
}
}
Any pointers would be appreciated. I've looked at a number of the iOS token refreshing tickets and I see lots of stale questions, but none with a workable solution.
Upvotes: 1
Views: 274
Reputation: 2140
So after some thinking about this issue, I realized a couple things.
So with those two pieces of information in hand, I was able in side of the [client silentGoogleAuthentication]; call capture the result of the trySilentAuthentication call and then with that assign the results to the correct place in the code and then just return a boolean to the function that made the initial call to [client silentGoogleAuthentication] and keep going. like so:
// Try signing in silently so user doesn't have to be prompted again
BOOL authResponse = [signIn trySilentAuthentication];
if (authResponse) {
NSLog(@"successful auth");
NSLog(@"idToken is %@", [GPPSignIn sharedInstance].idToken);
self.accountType = AuthTypeGoogle;
self.password = [GPPSignIn sharedInstance].idToken;
[self updateCredentials];
return true;
} else {
return false;
}
Upvotes: 1