2013-02-01 22 views
10

Jak wdrożyć aplikację Oauth na iPada?AFOAuth2Tenient klienta i odświeżania

W jaki sposób AFOAuth2Client zarządza mechanizmem odświeżania tokena w Oauth 2.0?

Czy istnieje jakaś metoda wdrożenia go w klasie lub czy musimy go wdrożyć na swój własny sposób? Jak sprawdzić token wygasł, czy nie?

Odpowiedz

11

Sposób, w jaki to rozwiązałem, polega na zawijaniu wszystkich moich żądań za pomocą bloku kodu, który w razie potrzeby odświeży token dostępu, np.

Dodaj kilka typedefs za sukces i porażka bloków:

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

Następnie metoda prośba brzmi:

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

A metoda, która sprawdza tokena wygaśnięcia i odświeża je, jeśli potrzebne jest:

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

Pełny kod źródłowy jest na GitHub: https://github.com/yellowfeather/rails-saas-ios.

+0

Ponadto można przenieść przechowywanie poświadczenia do ustawcy właściwości. – conradev

+2

Wygląda na to, że jest to zależne od terminu expires_in na tokenie, który zakłada, że ​​twój zegar jest ściśle zsynchronizowany z serwerem, nawet po opóźnieniu sieciowym (co może lub nie jest problemem) i że twój serwer rzeczywiście ustawia wartość expires_in prawidłowo. expires_in jest zalecane, ale nie jest wymagane w specyfikacji. Oznacza to, że na serwerach, które nie obsługują expires_in, odświeżanie powinno zostać wykonane po otrzymaniu błędu na żądanie z tokenem. Typowym błędem wyzwalającym odświeżenie jest 401. Chciałem tylko zauważyć, że chociaż to rozwiązanie może działać, może nie zawsze działać. – ptoinson

+0

@ptoinson Masz rację, a ja napotykam na ten problem, czy masz próbkę kodu do udostępnienia, która wykonuje odświeżenie, a następnie wysyła żądanie z odświeżonym tokenem? Próbuję obserwować AFNetworkingOperationDidFinishNotification, ale nie mogę wymyślić satysfakcjonującego rozwiązania. – Newcode

Powiązane problemy