Zaprojektowany do uwierzytelniania na Facebooku w aplikacji na iOS, która również korzysta z zabezpieczonej usługi internetowej

402

Cel: Pozwól użytkownikowi na uwierzytelnienie za pomocą Facebooka w aplikacji na iOS, która wymaga dostępu do chronionej usługi internetowej, którą prowadzę.

Założenia: Istnieje natywny system uwierzytelniania (i rejestracji) dla tych użytkowników, którzy zdecydują się nie używać Facebooka do logowania.

Detale:

  • Załóżmy, że chcemy zaoferować opcję zalogowania się przez Facebooka bez tworzenia osobnego konta / poświadczeń dla naszego systemu.
  • Ponieważ obsługujemy nasz własny natywny mechanizm uwierzytelniania (nazwa użytkownika i hasło), mamy własne identyfikatory użytkownika i wystawiamy token uwierzytelnienia, który jest używany do kolejnych interakcji po początkowej weryfikacji poświadczeń.

Jestem zaskoczony, że Facebook nie ma najlepszych praktyk w tym zakresie w dokumentacji dla programistów. Cała istniejąca dokumentacja zakłada albo, że budujesz FB na stronie internetowej, albo samodzielną aplikację mobilną bez usługi wymagającej uwierzytelnienia.

Oto moje wstępne przemyślenia na temat tego, jak to zostanie zaprojektowane, ale chcę sprawdzić poprawność pod kątem poprawności.

  1. Klient wyświetla login Facebook iOS
  2. Użytkownik interfejsu użytkownika loguje się przy użyciu poświadczeń Facebooka i otrzymuje token dostępu
  3. Aplikacja iOS przekazuje token dostępu do naszego serwera
  4. Nasz serwer rozmawia z interfejsem API wykresu FB za pomocą tokena dostępu, aby (a) zweryfikować token i (b) uzyskać identyfikator użytkownika FB dla tego tokena dostępu.

    np. nasz serwer wywołałby https://graph.facebook.com/me/?access_token=XYZ, co zwróciłoby informacje o profilu w obiekcie JSON

  5. Zakładając, że jest poprawny, nasz serwer wyodrębnia identyfikator użytkownika z obiektu JSON i sprawdza, czy użytkownik ma już konto. Jeśli tak, wydajemy naszemu klientowi własny bilet autoryzacyjny do wykorzystania w tej sesji. Jeśli użytkownik nie ma konta, tworzymy nowe z identyfikatorem użytkownika Facebooka, przypisujemy własny unikalny identyfikator użytkownika i wystawiamy nasz bilet autoryzacji.

  6. Klient następnie przekazuje bilet uwierzytelniający z powrotem przy kolejnych interakcjach wymagających uwierzytelnienia.

Wydaje mi się to właściwym podejściem, ale nie jestem pewien, czy brakuje mi czegoś niesamowicie podstawowego i podążam niewłaściwą (skomplikowaną) ścieżką.

TMC
źródło
1
Jak to rozwiązano? Patrzę również na przekazanie tokena dostępu i rozruszanie użytkownika na serwerze. Niby akademicki, ale pytam.
Chris Van Buskirk
To była moja implementacja z użyciem szyn i opracowania: stackoverflow.com/questions/7232490/…
Matt
Dlaczego nie przekazać całego auth_hash zamiast wykonywać dwa wywołania do FB API (jedno z urządzenia iOS i raz z serwera)?
bsiddiqui,
1
Co zrobić, jeśli chcesz zalogować się z innego urządzenia (co oznacza, że ​​nie masz biletu autoryzacji)? A jeśli właśnie dostaniesz nowy bilet uwierzytelniający, co uniemożliwi komuś przechwycenie identyfikatora / tokena Facebooka po drodze i użycie go na własnym urządzeniu?
Amitloaf
Z ciekawości w kroku 5, po co wydawać własny bilet uwierzytelniający? Czy nie możesz użyć tokena dostępu do Facebooka przy każdym kolejnym połączeniu z serwerem? Zdaję sobie sprawę, że wymagałoby to połączenia z serwera do interfejsu API Facebooka dla każdej aplikacji -> połączenia z serwerem, a nie tylko pierwszego.
Anders

Odpowiedzi:

80

Właśnie sobie z tym poradziłem i oto część, która mnie ugryzła:

W kroku 5 ... Użytkownik może zarejestrować konto w Tobie całkowicie oddzielnie od swojego identyfikatora na Facebooku, prawda? Potem logują się za pomocą Facebooka .... Właśnie założyłeś im drugie konto i straciłeś pierwsze.

Musi istnieć sposób na zalogowanie się do usługi internetowej, a następnie zalogowanie się na Facebooku i przechwycenie powiązania między identyfikatorem Facebooka a kontem lokalnym.

Poza tym twój plan brzmi solidnie.

Aktualizacja : Facebook dodał dokument opisujący taki scenariusz TUTAJ

Dan Ray
źródło
7
Tak, zastanowiłem się nad tym i jesteś na miejscu. Planujemy scalenie kont, jeśli jest to ten sam adres e-mail, a jeśli nie, stworzymy inny sposób ich scalenia.
TMC
Z której biblioteki serwera korzystasz po stronie serwera, aby wysłać żądanie?
TimLeung,
7
@TimLeung - Rozumiem, że token dostępu osadza identyfikator aplikacji i że nie możesz mieć tokena dostępu BEZ upieczonego w nim identyfikatora aplikacji.
Dan Ray
1
@TimLeunge: Korzystamy z interfejsu API Graph dla żądań z tokenem dostępu użytkownika.
TMC
29

Użyj https, aby przesłać token uwierzytelnienia na swój serwer, jak podaje Facebook

Udostępnianie tokenów dostępu

Nasze zasady dotyczące danych wyraźnie zabraniają udostępniania tokena dostępu do Twojej aplikacji dowolnej innej aplikacji. Zezwalamy jednak programistom na udostępnianie Tokenów między implementacją natywną a implementacją serwera tej samej aplikacji (tj. Przy użyciu tego samego identyfikatora aplikacji), o ile transfer odbywa się za pomocą HTTPS.

zoomcrypt
źródło
16

Jednym z problemów, jaki widzę w tej strategii, jest to, że ktoś może dać token dostępu uzyskany dla innej aplikacji na Facebooku. O ile mi wiadomo, nie ma sposobu, aby sprawdzić, czy token dostępu jest przeznaczony dla Twojej aplikacji, więc po prostu zacznij z niego korzystać.

Nie brzmi to jednak zbyt szkodliwie. Zasadniczo ludzie / aplikacje starają się chronić tokeny dostępu, zamiast je udostępniać.

Jednym z możliwych sposobów wykorzystania tego byłoby, gdyby ktoś stworzył własną stronę internetową lub aplikację mobilną, uzyskał tokeny dostępu dla swoich użytkowników i spróbował je uwierzytelnić, używając twojego API. Jeśli to się powiedzie (użytkownik ma konto na Facebooku w Twojej witrynie), złośliwa witryna będzie mogła użyć interfejsu API podszywającego się pod użytkownika.

To trochę długa szansa, ale myślę, że to może zadziałać.

Edycja: Wygląda na to, że istnieje sposób na sprawdzenie poprawności tokena dostępu. Zobacz odpowiedź @Daaniel na pytanie Uzyskaj identyfikator aplikacji z tokena dostępu użytkownika (lub sprawdź aplikację źródłową tokena) .

bluszcz
źródło
Wysyłanie appsecret_proofpowinno temu zapobiec (patrz tutaj )
Tony
@ Tony możesz wyjaśnić, w jaki sposób appsecret_proofpomaga tutaj? O ile rozumiem, służy to udowodnieniu Facebookowi, że serwer zna tajny klucz. Ivant miał jednak na myśli złośliwą aplikację, która uzyskiwała tokeny, a następnie wysyłała je do interfejsu API. Serwer może zweryfikować identyfikator aplikacji, ale złośliwa aplikacja może łatwo sfałszować identyfikator aplikacji. Więc ... jak można to złagodzić?
YSK
3
Możesz sprawdzić, czy token został wygenerowany dla Twojej aplikacji, przez https://graph.facebook.com/app/?access_token=[user_access_token]którą zwraca identyfikator aplikacji, a następnie porównać identyfikatory aplikacji
Nader Alexan
4

twoje rozwiązanie działa całkowicie.

Może alternatywa: dlaczego nie pobrać wiadomości e-mail od klienta z początkowego żądania usługi społecznościowej i wysłać do swojej usługi sieciowej? Usługa internetowa może po prostu przechowywać wiadomość e-mail, a może także dostawcę usług społecznościowych. Rozumiem, że twoja usługa internetowa nie będzie w stanie zweryfikować, skąd pochodzi wiadomość e-mail, ale czy nie ma relacji o wysokim zaufaniu między twoją usługą a klientem? Jeśli tak, wydaje się, że możesz polegać na wiadomości e-mail pochodzącej z właściwego miejsca. Ktoś, proszę, daj mi znać, co oczywistego brakuje mi, co sprawia, że ​​podejście oparte na e-mailu jest głupie ...

Amsterdam
źródło
3
Mogę łatwo dowiedzieć się, w jaki sposób klient rozmawia z serwerem. Potem mógłbym po prostu rzucać na nią e-mailami, dopóki nie trafię. Zawsze musi istnieć jakaś forma weryfikacji
Chris
5
Wysokie zaufanie i klient? Proszę nigdy w tym samym zdaniu. Oczywiście z wyjątkiem poprzedniego zdania.
EralpB