Ios AFOAuth2Client和刷新令牌

Ios AFOAuth2Client和刷新令牌,ios,ipad,oauth-2.0,afnetworking,Ios,Ipad,Oauth 2.0,Afnetworking,如何在iPad应用程序中实现Oauth 在oauth 2.0中,AFOAuth2Client如何管理刷新令牌机制 是否有任何方法在类内部实现它,或者我们必须以自己的方式实现它?如何检查令牌是否过期?我解决这一问题的方法是用代码块包装我的所有请求,该代码块将在需要时刷新访问令牌,例如 为成功和失败块添加一些typedef: typedef void (^YFRailsSaasApiClientSuccess)(AFJSONRequestOperation *operation, id respon

如何在iPad应用程序中实现Oauth

在oauth 2.0中,AFOAuth2Client如何管理刷新令牌机制


是否有任何方法在类内部实现它,或者我们必须以自己的方式实现它?如何检查令牌是否过期?

我解决这一问题的方法是用代码块包装我的所有请求,该代码块将在需要时刷新访问令牌,例如

为成功和失败块添加一些typedef:

typedef void (^YFRailsSaasApiClientSuccess)(AFJSONRequestOperation *operation, id responseObject);
typedef void (^YFRailsSaasApiClientFailure)(AFJSONRequestOperation *operation, NSError *error);
那么请求方法是:

- (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];
}
检查令牌到期并在需要时刷新它的方法是:

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

GitHub上提供了完整的源代码:。

此外,您可以将凭证的存储移动到属性的setter。这似乎取决于令牌上的expires\u,该令牌假定您的时钟与服务器非常同步,即使在网络延迟之后(这可能是问题,也可能不是问题)而且您的服务器确实正确地设置了expires_in值。建议使用expires_in,但规范中不要求使用expires_in。这表示在不支持expires_in的服务器上,应在收到带有令牌的请求的错误后进行刷新。触发刷新的典型错误是401。我只是想指出,虽然这个解决方案可能有效,但可能并不总是有效。@ptoinson您是对的,我遇到了这个问题,您是否有任何代码示例可以共享,以执行刷新,然后使用刷新的令牌发送请求?我试图观察AFNetworkingOperationDidFinishNotification,但无法找到令人满意的解决方案。@新代码:我创建了一个AFHTTPClient子类,该子类使用委托模式和扩展故障块来获取新令牌:只需根据您的需要调整现有委托或实现您自己的委托即可。请注意,还有其他(可能更容易)的可能性来确保正确的凭据,包括使用操作依赖项和对安全资源的(小的、固定的)请求,或者挂接到AFNetworking的现有身份验证机制。取决于您的服务器,这些可能更可取,也可能不可取。@Newcode:我已经创建了解决此问题的代码。但是,我在NSN网络之上有几个层,包括RestKit。我几乎只是查找401响应,缓存生成401的请求,刷新令牌,然后重试触发401的请求。它变得相当复杂,因为我也可以有并行的请求,并且可以在任何一个请求中获得401。不想在已经进行令牌刷新时进行令牌刷新。patric.schenke的代码会帮你完成大部分任务。