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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With