2013-02-01 12 views
10

Wie die Oauth in iPad-Anwendung zu implementieren?AFOAuth2Client und Refresh-Token

Wie verwaltet AFOAuth2Client den Mechanismus für das Aktualisieren von Token in oauth 2.0?

Gibt es eine Methode, um es innerhalb der Klasse zu implementieren, oder müssen wir es auf unsere eigene Weise implementieren? Wie überprüfe ich, ob das Token abgelaufen ist oder nicht?

Antwort

11

Die Weise, die ich das gelöst habe, ist, alle meine Anfragen mit einem Codeblock zu verpacken, der das Zugangstoken bei Bedarf z.

einige typedefs für Erfolg und Misserfolg Blöcke hinzufügen:

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

die Anforderungsmethode Dann ist:

- (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]; 
} 

Und die Methode, die für Token Ablauf überprüft und aktualisiert es erforderlich, wenn ist:

- (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); 
            } 
           }]; 
} 

Der vollständige Quellcode ist auf GitHub: https://github.com/yellowfeather/rails-saas-ios.

+0

Zusätzlich können Sie das Speichern der Anmeldeinformationen in den Setter der Eigenschaft verschieben. – conradev

+2

Es scheint, dass dies von expires_in auf dem Token abhängig ist, das davon ausgeht, dass Ihre Uhr ziemlich synchron mit dem Server ist, selbst nach Netzwerkverzögerung (was ein Problem sein kann) und dass Ihr Server tatsächlich den expires_in Wert setzt richtig. expires_in wird empfohlen, ist aber in der Spezifikation nicht erforderlich. Dies bedeutet, dass auf Servern, die expires_in nicht unterstützen, die Aktualisierung durchgeführt werden sollte, nachdem ein Fehler für eine Anforderung mit dem Token erhalten wurde. Typisch ist der Fehler beim Auslösen einer Aktualisierung 401. Ich wollte nur bemerken, dass diese Lösung zwar funktioniert, aber nicht immer funktioniert. – ptoinson

+0

@ Ptoinson Sie haben Recht und ich bin in diesem Problem, haben Sie ein Codebeispiel zu teilen, die eine Aktualisierung durchführt und senden Sie dann die Anfrage mit dem aktualisierten Token? Ich versuche AFNetworkingOperationDidFinishNotification zu beobachten, kann aber keine befriedigende Lösung finden. – Newcode

Verwandte Themen