Lithu T.V
Lithu T.V

Reputation: 20021

How to implement AFOAuth2Client to get refresh token?

I am trying tro implement the Oauth authentication in my iphone application.

Scenario

Created a subclass of the AFOAuth2Client and override the method

- (void)authenticateWithUsernameAndPassword:(NSString *)username
                                   password:(NSString *)password
                                    success:(void (^)(AFOAuthCredential *credential))success
                                    failure:(void (^)(NSError *error))failure;

to authenticate and set the auth token to header in the client and is using its sharedInstance to call the web services (using Restkit).

Question What i cant make is about the refresh token.I have the api for getting the refresh token.

  1. How will my app know the token is expired?
  2. Where to check token expired and call to get the new refresh token
  3. Is there an option in AFOAuth2Client to do it?

Upvotes: 3

Views: 1438

Answers (1)

Alex
Alex

Reputation: 538

- (NSURLSessionTask *)authenticateUsingOAuthWithURLString:(NSString *)URLString 
                               refreshToken:(NSString *)refreshToken
                               success:(void (^)(AFOAuthCredential *credential))success
                               failure:(void (^)(NSError *error))failure;

Using this method you can present new refreshToken to the auth Server. And before that you need to save the AFOAuthCredential as NSData in the user defaults and then when you call the api retrieve the AFOAuthCredential and check if it is expired or not using this method.

func refreshTokenIfUnavailable(completionHandler : @escaping(_ finished:Bool,_ error:Error) -> ()) {
    let credentialData = UserDefaults.standard.object(forKey: CREDENTIAL) as? NSData

    if let credentialData = credentialData {
        let credential = NSKeyedUnarchiver.unarchiveObject(with: credentialData as Data) as? AFOAuthCredential

        if let _ = credential
        {
            if credential!.isExpired {
                let urlString = OAUTH_BASE_URL
                let url = URL(string: urlString)
                let oAuthManager = AFOAuth2Manager(baseURL: url!, clientID: YOUR_AUTH_CLIENT_ID secret: YOUR_AUTH_SECRET_ID)
                oAuthManager.authenticateUsingOAuth(withURLString: "oauth/token", refreshToken: (credential?.refreshToken)!, success: { (credential) in
                    self.saveAccessToken(credential: credential)
                    completionHandler(true,YOUR_ERROR))
                }, failure: { (error) in
                    completionHandler((credential != nil),NSError(domain: "", code: 204, userInfo: [NSLocalizedDescriptionKey: error.localizedDescription]))
                })
            }
            completionHandler((credential != nil),YOUR_ERROR_MESSAGE))
        }
    }
}

func saveAccessToken(credential : AFOAuthCredential) {

    KeychainService.saveAccessToken(service: ACCESS_TOKEN as NSString, data: credential.accessToken as NSString)

    let credentialData = NSKeyedArchiver.archivedData(withRootObject: credential)
    let userDefaults = UserDefaults.standard
    userDefaults.set(credentialData, forKey: "credentials")
}

Hope this one meet your need. Happy Coding :)

Upvotes: 2

Related Questions