Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AFOAuth2Client and refresh token

How to implement the Oauth in iPad application?

How does AFOAuth2Client manages refreshing token mechanism in oauth 2.0?

Is there any method to implement it inside the class or do we have to implement it in our own way? How to check the token is expired or not?

like image 468
Lithu T.V Avatar asked Feb 01 '13 03:02

Lithu T.V


People also ask

What is refresh token in OAuth2?

An OAuth Refresh Token is a string that the OAuth client can use to get a new access token without the user's interaction. A refresh token must not allow the client to gain any access beyond the scope of the original grant.

What is the difference between token and refresh token?

The difference between a refresh token and an access token is the audience: the refresh token only goes back to the authorization server, the access token goes to the (RS) resource server. Also, just getting an access token doesn't mean the user's logged in.

What is a refresh token?

A refresh token is a special token that is used to obtain additional access tokens. This allows you to have short-lived access tokens without having to collect credentials every time one expires.

How can I get OAuth refresh token?

Because OAuth2 access expires after a limited time, an OAuth2 refresh token is used to automatically renew OAuth2 access. Click the tab for the programming language you're using, and follow the instructions to generate an OAuth2 refresh token and set up the configuration file for your client.


1 Answers

The way that I have solved this is to wrap all my requests with a code block which will refresh the access token if needed e.g.

Add some typedefs for success and failure blocks:

typedef void (^YFRailsSaasApiClientSuccess)(AFJSONRequestOperation *operation, id responseObject);
typedef void (^YFRailsSaasApiClientFailure)(AFJSONRequestOperation *operation, NSError *error);

Then the request method is:

- (void)getProductsWithSuccess:(YFRailsSaasApiClientSuccess)success failure:(YFRailsSaasApiClientFailure)failure {
    NSLog(@"getProductsWithSuccess");

    success = ^(AFJSONRequestOperation *operation, id responseObject) {
        [self getPath:@"api/1/products"
           parameters:nil
              success:^(AFHTTPRequestOperation *operation, id responseObject) {
                  NSLog(@"getProductsWithSuccess: success");

                  // TODO: handle response

                  if (success) {
                      success((AFJSONRequestOperation *)operation, responseObject);
                  }
              } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                  NSLog(@"getProductsWithSuccess: failure");
              if (failure) {
                  failure((AFJSONRequestOperation *)operation, error);
              }
          }];
    };

    [self refreshAccessTokenWithSuccess:success failure:failure];
}

And the method which checks for token expiry and refreshes it if needed is:

- (void)refreshAccessTokenWithSuccess:(YFRailsSaasApiClientSuccess)success failure:(YFRailsSaasApiClientFailure)failure {
    NSLog(@"refreshAccessTokenWithSuccess");

    if (self.credential == nil) {
        if (failure) {
            NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary];
            [errorDetail setValue:@"Failed to get credentials" forKey:NSLocalizedDescriptionKey];
            NSError *error = [NSError errorWithDomain:@"world" code:200 userInfo:errorDetail];
            failure(nil, error);
        }
        return;
    }  

    if (!self.credential.isExpired) {
        NSLog(@"refreshAccessTokenWithSuccess: credential has not expired");

        if (success) {
            success(nil, nil);
        }
        return;
    }

    NSLog(@"refreshAccessTokenWithSuccess: refreshing credential");

    [self authenticateUsingOAuthWithPath:@"oauth/token"
                            refreshToken:self.credential.refreshToken
                                 success:^(AFOAuthCredential *newCredential) {
                                     NSLog(@"Successfully refreshed OAuth credentials %@", newCredential.accessToken);
                                     self.credential = newCredential;
                                     [AFOAuthCredential storeCredential:newCredential
                                                     withIdentifier:self.serviceProviderIdentifier];

                                     if (success) {
                                         success(nil, nil);
                                     }
                                 }
                                 failure:^(NSError *error) {
                                     NSLog(@"An error occurred refreshing credential: %@", error);
                                     if (failure) {
                                         failure(nil, error);
                                     }
                                 }];
}

Full source code is up on GitHub: https://github.com/yellowfeather/rails-saas-ios.

like image 180
ChrisR Avatar answered Sep 25 '22 02:09

ChrisR