【问题标题】:How to automatically refresh expired token with AFOAuth2Manager?如何使用 AFOAuth2Manager 自动刷新过期令牌?
【发布时间】:2015-05-10 20:53:00
【问题描述】:

我正在为受 OAuth2 保护的服务器编写一个小型 iOS 客户端。

我想知道是否可以使用AFOAuth2Manager [here] 自动刷新过期令牌。

这个想法是,当服务器响应 401 时刷新客户端的逻辑,或者当刷新方法返回 401 时引发错误的逻辑应该很常见,所以它可能集成在某个库中。

【问题讨论】:

  • 你找到解决办法了吗?
  • 目前还没有。我实现了自己的逻辑
  • 你能发布你的样本或解释你做了什么吗?我也在找一样的。

标签: ios oauth-2.0 afnetworking afnetworking-2


【解决方案1】:

Swift 解决方案与 Alamofire 4.0。基于 RequestAdapter 和 RequestRetrier 协议:example link

【讨论】:

    【解决方案2】:

    我正在寻找这个问题的答案,"Matt", the creator of AFNetworking, suggest this:

    我发现处理这个问题的最佳解决方案是使用依赖 NSOperations 在任何之前检查一个有效的、未过期的令牌 允许传出请求通过。到时候,就看 开发人员确定刷新的最佳行动方案 令牌,或首先获得一个新令牌。

    简单但有效?,现在试试,会用报告编辑...

    【讨论】:

      【解决方案3】:

      我创建了AFOAuth2Manager 的子类

      在这个子类中我重写了这个方法:

      - (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
                                                          success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                                                          failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {
          return [self HTTPRequestOperationWithRequest:request
                                               success:success
                                               failure:failure
                                 checkIfTokenIsExpired:YES];
      }
      

      使用附加参数调用自定义方法:checkIfTokenIsExpired。这是为了避免无限循环所必需的。

      这个方法的实现是直截了当的:如果我们不需要检查令牌,只需调用超类即可。

      if (!checkIfTokenIsExpired) {
              return [super HTTPRequestOperationWithRequest:request
                                                    success:success
                                                    failure:failure];
          }
      

      否则我们使用自定义失败块执行请求

      else {
              return [super HTTPRequestOperationWithRequest:request
                                                    success:success
                                                    failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
                  if (operation.response.statusCode == ERROR_CODE_UNAUTHORIZED) { //1
                      [self reauthorizeWithSuccess: ^{ //2
                          NSURLRequest *req = [self.requestSerializer requestByAddingHeadersToRequest:request]; //3
                          AFHTTPRequestOperation *moperation = [self HTTPRequestOperationWithRequest:req //4
                                                                                             success:success
                                                                                             failure:failure
                                                                               checkIfTokenIsExpired:NO];
      
                          [self.operationQueue addOperation:moperation]; //5
                      }                    failure: ^(NSError *error) {
                          failure(nil, error);
                      }];
                  }
                  else {
                      failure(operation, error); //6
                  }
              }];
          }
      
      • //1:检查http status code,如果401尝试自动重新授权。
      • //2:reauthorize 是一个私有方法,它使用AFOAuthManager 来刷新令牌。
      • //3:在这种情况下,我们重新授权成功,我们希望重新提交之前请求的副本。 requestByAddingHeadersToRequest: 方法只是复制上一个请求中的所有标头字段。
      • //4:创建上一个请求的副本,但是这次最后一个参数是false,因为我们不想再次检查! successBlockfailureBlock 与之前的请求相同。
      • //5:将操作添加到队列中。
      • //6:如果重新授权方法失败,只需调用失败块。

      【讨论】:

      • 这是一个了不起的回应!我很好奇:您将如何实现reauthorizeWithSuccess: 方法以确保不会同时触发一个以上刷新令牌的请求?同样:如果您正在刷新令牌,您不希望其他请求使用当前过期的令牌触发。实现它的简单方法是什么?暂停队列似乎有点毛骨悚然......
      • 如果你喜欢这个回复,你可以投票吗? :) 关于您的问题,没有针对多个请求的具体检查。在我的项目中,无法同时有多个请求,所以对我来说没问题。否则我会建议两种方法: 1. 什么都不做。即使您有 3 个并行调用并且您正在刷新令牌,您最终也会收到 3 个不必要的请求,这有什么大不了的吗?取决于项目。 2.在刷新令牌任务期间添加一个标志变量(原子)并将其设置为true。如果您的请求失败并且此布尔值为真,请在 0.1 秒后重试。
      【解决方案4】:

      不幸的是,我没有找到任何框架来解决这个问题,所以我写了一个简短的包装 AFNetworking (如果有人感兴趣,我可以在 github 上发布) 逻辑是执行请求,如果是http响应401,尝试刷新auth-token,完成后重新执行之前的请求。

      【讨论】:

      • 请把它放到 GitHub 上好吗?
      • 嗨 IgnazioC,请提供示例谢谢!
      猜你喜欢
      • 1970-01-01
      • 2016-09-10
      • 2020-11-11
      • 2019-04-07
      • 2021-10-22
      • 2021-11-16
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多