Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to automatically refresh expired token with AFOAuth2Manager?

I'm writing a small iOS client for a server protected with OAuth2.

I'm wondering if is it possible using AFOAuth2Manager [here] auto-refreshing the expired token.

The idea is that the logic for refreshing the client when the server responds with a 401, or raise an error when the refresh method returns a 401 should be quite common, so probably it is integrated in some library.

like image 558
IgnazioC Avatar asked Mar 09 '15 15:03

IgnazioC


People also ask

Can you refresh an expired token?

Once they expire, client applications can use a refresh token to "refresh" the access token. That is, a refresh token is a credential artifact that lets a client application get new access tokens without having to ask the user to log in again.

How do I trigger a refresh token?

To use the refresh token, make a POST request to the service's token endpoint with grant_type=refresh_token , and include the refresh token as well as the client credentials if required.


Video Answer


1 Answers

I created a subclass of AFOAuth2Manager

In this subclass I override this method:

- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
                                                    success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                                                    failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {
    return [self HTTPRequestOperationWithRequest:request
                                         success:success
                                         failure:failure
                           checkIfTokenIsExpired:YES];
}

calling a custom method with an additional parameter: checkIfTokenIsExpired. This is required in order to avoid infinite loops.

The implementation of this method is straigth forward: if we don't need to check the token just call the super class.

if (!checkIfTokenIsExpired) {
        return [super HTTPRequestOperationWithRequest:request
                                              success:success
                                              failure:failure];
    }

otherwise we perform the request with a custom failure block

else {
        return [super HTTPRequestOperationWithRequest:request
                                              success:success
                                              failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
            if (operation.response.statusCode == ERROR_CODE_UNAUTHORIZED) { //1
                [self reauthorizeWithSuccess: ^{ //2
                    NSURLRequest *req = [self.requestSerializer requestByAddingHeadersToRequest:request]; //3
                    AFHTTPRequestOperation *moperation = [self HTTPRequestOperationWithRequest:req //4
                                                                                       success:success
                                                                                       failure:failure
                                                                         checkIfTokenIsExpired:NO];

                    [self.operationQueue addOperation:moperation]; //5
                }                    failure: ^(NSError *error) {
                    failure(nil, error);
                }];
            }
            else {
                failure(operation, error); //6
            }
        }];
    }
  • //1: check the http status code, if 401 try to automatically re-authorize.
  • //2: reauthorize is a private mathod that uses AFOAuthManager to refresh the token.
  • //3: In this case we are re-authorized with success and we want to resubmit a copy of the previous request. The method requestByAddingHeadersToRequest: just copy all the header fields from the previous request.
  • //4: Create a copy of the previous request, but this time the last parameter is false because we don't want check again! The successBlock and failureBlock are the same of the previous request.
  • //5: Add the operation to the queue.
  • //6: If the reauthorize method fails just call the failure block.
like image 58
IgnazioC Avatar answered Oct 05 '22 23:10

IgnazioC