2013-02-01 19 views
10

Cách triển khai ứng dụng Oauth trong iPad?AFOAuth2Thẻ làm mới và làm mới

AFOAuth2Client quản lý cơ chế mã thông báo làm mới trong oauth 2.0 như thế nào?

Có phương pháp nào để triển khai nó trong lớp hay chúng ta phải thực hiện nó theo cách riêng của chúng ta? Làm cách nào để kiểm tra mã thông báo đã hết hạn hay không?

Trả lời

11

Cách tôi đã giải quyết vấn đề này là bao gồm tất cả các yêu cầu của tôi với một khối mã sẽ làm mới mã thông báo truy cập nếu cần, ví dụ:

Thêm một số typedefs cho sự thành công và thất bại khối:

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

Sau đó các phương thức yêu cầu là:

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

Và phương pháp mà kiểm tra hết hạn thẻ và làm mới nó nếu cần thiết là:

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

Mã nguồn đầy đủ được bật trên GitHub: https://github.com/yellowfeather/rails-saas-ios.

+0

Ngoài ra, bạn có thể di chuyển việc lưu trữ thông tin xác thực đến người đặt của thuộc tính. – conradev

+2

Có vẻ như điều này phụ thuộc vào expires_in trên mã thông báo giả sử đồng hồ của bạn khá đồng bộ với máy chủ, ngay cả sau khi trễ mạng (có thể hoặc không có vấn đề) và máy chủ của bạn thực sự đặt giá trị expires_in đúng. expires_in được khuyến nghị, nhưng không bắt buộc trong thông số kỹ thuật. Điều này chỉ ra rằng trên các máy chủ không hỗ trợ expires_in, việc làm mới phải được thực hiện sau khi nhận được một lỗi trên một yêu cầu với mã thông báo. Điển hình lỗi để kích hoạt làm mới là 401. Chỉ cần lưu ý rằng trong khi giải pháp này có thể hoạt động, nó có thể không phải lúc nào cũng hoạt động. – ptoinson

+0

@ptoinson Bạn nói đúng và tôi đang gặp sự cố này, bạn có mẫu mã nào để chia sẻ thực hiện làm mới và sau đó gửi yêu cầu bằng mã thông báo làm mới không? Tôi đang cố gắng để quan sát AFNetworkingOperationDidFinishNotification nhưng không thể đưa ra một giải pháp thỏa mãn. – Newcode