2015-03-09 22 views
10

Piszę małego klienta iOS dla serwera chronionego przez OAuth2.Jak automatycznie odświeżyć wygasły token za pomocą AFOAuth2Manager?

Zastanawiam się, czy możliwe jest automatyczne odświeżenie wygasłego tokena za pomocą AFOAuth2Manager [here].

Pomysł polega na tym, że logika odświeżania klienta, gdy serwer odpowiada 401, lub podnoszą błąd, gdy metoda odświeżania zwraca 401, powinna być dość powszechna, więc prawdopodobnie jest zintegrowana z pewną biblioteką.

+0

Czy znaleziono żadnych rozwiązań? – iPeo

+0

Nie tak daleko. Zaimplementowałem własną logikę – IgnazioC

+0

czy możesz zamieścić swoją próbkę lub wyjaśnić, co zrobiłeś? Szukam tego samego. – cableload

Odpowiedz

14

stworzyłem podklasę AFOAuth2Manager

W tej podklasy zastąpić tę metodę:

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

wywołanie metody niestandardowej z dodatkowym parametrem: checkIfTokenIsExpired. Jest to wymagane, aby uniknąć nieskończonych pętli.

Implementacja tej metody jest prosta: jeśli nie musimy sprawdzać tokena, wystarczy zadzwonić do super klasy.

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

inaczej możemy wykonać żądania z bloku zwyczaj awarii

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: Sprawdź http status code, jeśli 401 próbować automatycznie ponownie-autoryzacji.
  • // 2: ponowna autoryzacja to prywatna matematyka korzystająca z AFOAuthManager do odświeżenia tokena.
  • // 3: W tym przypadku jesteśmy ponownie upoważnieni z powodzeniem i chcemy ponownie przesłać kopię poprzedniego wniosku. Metoda ta polega tylko na skopiowaniu wszystkich pól nagłówka z poprzedniego żądania.
  • // 4: Utwórz kopię poprzedniego żądania, ale tym razem ostatni parametr jest fałszywy, ponieważ nie chcemy ponownie sprawdzać! successBlock i failureBlock są takie same jak poprzednie żądanie.
  • // 5: Dodaj operację do kolejki.
  • // 6: Jeśli metoda ponownego autoryzowania się nie powiedzie, po prostu wywołaj blok awarii.
+1

To fantastyczna odpowiedź! Jestem ciekawy: jak zaimplementować metodę 'reauthorizeWithSuccess:', aby upewnić się, że w tym samym czasie nie zostanie uruchomione więcej niż jedno żądanie odświeżania tokenów? Podobnie: jeśli jesteś w trakcie odświeżania tokenów, nie chcesz, aby inne żądania były uruchamiane z bieżącym, wygasłym tokenem. W jaki prosty sposób to wdrożyć? Zawieszenie kolejki wydaje się być owłosione ... –

+1

Jeśli podoba ci się odpowiedź, możesz głosować w górę? :) O twoich pytaniach nie ma konkretnej kontroli dla wielu próśb. W moim projekcie nie ma sposobu na wielokrotne żądanie w tym samym czasie, więc dla mnie jest w porządku. W przeciwnym razie zasugeruję dwa podejścia: 1. nie rób nic specjalnego. Nawet jeśli masz 3 połączenia równolegle i odświeżasz Tocken, otrzymasz 3 niepotrzebne żądania, to jest wielka sprawa? zależy od projet. 2. Dodaj zmienną flagową (atomową) i ustaw ją jako true podczas zadania tokena odświeżania. Jeśli twoje żądanie się nie powiedzie, a wartość logiczna jest prawdziwa, po prostu spróbuj aferować 0,1 sekundy. – IgnazioC

+0

To rozwiązanie nie działa w przypadku AFNetworking3. – fvisticot

2

Niestety nie znaleziono żadnych ram dla rozwiązania tego problemu więc napisałem krótki owijkę wokół AFNetworking (jeśli ktoś jest zainteresowany mogę publikować na github) Logika jest do wykonania wniosku, aw przypadku odpowiedzi HTTP 401, spróbuj odświeżyć auth-token i po jego wykonaniu ponownie wykonać poprzednie żądanie.

+1

Czy możesz umieścić go na GitHub? – KutakMir

+0

cześć IgnazioC, proszę podać przykład Dzięki! – MaKo

0

szukałem odpowiedzi na ten problem i "Matt", the creator of AFNetworking, suggest this:

najlepszym rozwiązaniem Znalazłem radzenia sobie z tego jest użycie zależne NSOperations aby sprawdzić ważnego, un-wydychanym tokena zanim jakiekolwiek wychodzące żądanie będzie mogło przejść. W tym momencie programista musi ustalić, czy najlepiej jest odświeżyć ten token, czy też nabyć nowy.

Proste, ale skuteczne ?, próbuje teraz będzie zmieniać z raportu ...