2015-03-09 6 views
10

Я пишу небольшой клиент iOS для сервера, защищенного OAuth2.Как автоматически обновить токены с истекшим сроком действия с помощью AFOAuth2Manager?

Мне интересно, можно ли использовать AFOAuth2Manager [here] автообновление истекшего токена.

Идея состоит в том, что логика обновления клиента, когда сервер отвечает 401, или поднять ошибку, когда метод обновления возвращает 401, должен быть довольно распространенным, поэтому, вероятно, он интегрирован в некоторую библиотеку.

+0

Вы нашли какие-либо решения? – iPeo

+0

пока. Я реализовал свою собственную логику – IgnazioC

+0

вы можете разместить свой образец или объяснить, что вы сделали? Я ищу то же самое. – cableload

ответ

14

Я создал подкласс 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: Создайте копию предыдущего запроса, но на этот раз последний параметр является ложным, потому что мы не хотим снова проверять! successBlock и failureBlock совпадают с предыдущим запросом.
  • // 5: добавьте операцию в очередь.
  • // 6: Если метод reauthorize не работает, просто вызовите блок сбоя.
+1

Это фантастический ответ! Мне любопытно: как бы вы реализовали метод reauthorizeWithSuccess: 'для обеспечения того, чтобы одновременно не более одного запроса на обновление токенов? Аналогично: если вы находитесь в середине обновляющих токенов, вы не хотите, чтобы другие запросы запускались с текущим токеном с истекшим сроком действия. Какой простой способ реализовать это? Приостановка очереди выглядит вроде волосатой ... –

+1

Если вам нравится ответ, вы можете проголосовать? :) По вашим вопросам нет конкретной проверки нескольких запросов. В моем проекте нет способа иметь несколько запросов одновременно, поэтому для меня все в порядке. В противном случае я предлагаю два подхода: 1. Не делайте ничего особенного. Даже если у вас есть 3 вызова параллельно, и вы обновляете токен, вы получите в итоге 3 лишних запроса, это большое дело? зависит от проекта. 2. Добавьте переменную флага (атомный) и поместите ее в true во время задачи токена обновления. Если ваш запрос не выполняется, и это логическое значение истинно, просто повторите попытку 0.1 с. – IgnazioC

+0

Это решение не работает в AFNetworking3. – fvisticot

2

К сожалению, я не нашел рамки для решения этой проблемы, поэтому написал короткую обертку около AFNetworking (если кому-то интересно, я могу опубликовать ее на github) Логика заключается в выполнении запроса, а в случае ответа на HTTP 401, попробуйте обновить auth-токен и когда это будет сделано для повторного выполнения предыдущего запроса.

+1

Не могли бы вы поместить его на GitHub, пожалуйста? – KutakMir

+0

привет IgnazioC, пожалуйста, укажите пример Спасибо! – MaKo

0

Я искал ответ на эту проблему и "Matt", the creator of AFNetworking, suggest this:

лучшее решение, которое я нашел для решения этой проблемы является использование зависимых NSOperations для проверки действительного, снимите с истекшим сроком лексемы перед любым исходящий запрос разрешен. В этот момент разработчик должен определить лучший способ действий для обновления токена или приобретения нового в первую очередь.

Простой, но эффективный ?, пытается сейчас редактирует с отчетом ...

Смежные вопросы