Tworzę spokojną aplikację internetową, która używa popularnego frameworka internetowego na zapleczu, powiedzmy (rails, sinatra, flask, express.js). Idealnie, chciałbym rozwijać stronę klienta za pomocą Backbone.js. Jak zezwolić tylko mojej stronie klienta javascript na interakcję z tymi wywołaniami API? Nie chcę, aby te wywołania API były publiczne i były wywoływane przez curl
lub po prostu przez wpisanie łącza w przeglądarce.
92
Odpowiedzi:
Po pierwsze, jeśli twoje API jest używane przez twojego klienta JS, musisz założyć, że jest publiczne: Prosty debugger JS umieszcza atakującego w pozycji, w której może wysłać identyczne żądanie bajt po bajcie z wybrane przez siebie narzędzie.
To powiedziawszy, jeśli dobrze przeczytałem twoje pytanie, to nie jest to, czego chcesz uniknąć: To, czego naprawdę nie chcesz, to to, że twoje API jest zużywane (regularnie) bez udziału klienta JS. Oto kilka pomysłów, jak egzekwować, a przynajmniej zachęcać do korzystania z klienta:
Jestem pewien, że twoje API ma jakieś pole uwierzytelniania (np. Hash obliczany na kliencie). Jeśli nie, spójrz na to pytanie SO . Upewnij się, że używasz soli (lub nawet klucza API), który jest przekazywany klientowi JS na podstawie sesji (zakodowany na stałe). W ten sposób nieautoryzowany konsument Twojego interfejsu API jest zmuszony do znacznie większej pracy.
Podczas ładowania klienta JS zapamiętaj niektóre nagłówki HTTP (przychodzi mi na myśl agent użytkownika) i adres IP i poproś o ponowne uwierzytelnienie, jeśli ulegną zmianie, stosując czarne listy dla zwykłych podejrzanych. Zmusza to napastnika do ponownego dokładniejszego odrabiania pracy domowej.
Po stronie serwera pamiętaj o kilku ostatnich wywołaniach API, a przed zezwoleniem na kolejne sprawdź, czy logika biznesowa pozwala teraz na nowe: To uniemożliwia atakującemu skoncentrowanie wielu swoich sesji w jednej sesji z Twoim serwerem: W w połączeniu z innymi środkami ułatwi to wykrycie sprawcy.
Mógłbym nie powiedzieć tego z niezbędną jasnością: uważam, że niemożliwe jest całkowite uniemożliwienie sprawcy korzystania z Twojej usługi, ale możesz to tak utrudnić, że może to nie być warte zachodu.
źródło
Powinieneś zaimplementować jakiś system uwierzytelniania. Dobrym sposobem na rozwiązanie tego problemu jest zdefiniowanie pewnych oczekiwanych zmiennych nagłówka. Na przykład możesz mieć wywołanie interfejsu API uwierzytelniania / logowania, które zwraca token sesji. Kolejne wywołania Twojego interfejsu API będą oczekiwać, że token sesji zostanie ustawiony w zmiennej nagłówka HTTP o określonej nazwie, np. „Twój-api-token”.
Alternatywnie, wiele systemów tworzy tokeny dostępu lub klucze, które są oczekiwane (np. Youtube, facebook czy twitter) za pomocą jakiegoś systemu kont API. W takich przypadkach Twój klient musiałby przechowywać je w jakiś sposób w kliencie.
Wtedy wystarczy po prostu dodać czek sesji do środowiska REST i zgłosić wyjątek. Jeśli to w ogóle możliwe, kod statusu (aby był spokojny) byłby błędem 401.
źródło
Istnieje teraz otwarty standard o nazwie „JSON Web Token”,
patrz https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
źródło
Przepraszam @MarkAmery i Eugene, ale to jest niepoprawne.
Twoja aplikacja js + html (klient) działająca w przeglądarce MOŻE zostać skonfigurowana tak, aby wykluczyć nieautoryzowane bezpośrednie wywołania interfejsu API w następujący sposób:
Podczas uwierzytelniania zwracany jest „token”.
Po uwierzytelnieniu akceptowane będą tylko wywołania API z „tokenem” uwierzytelniania.
Oczywiście na tym etapie tylko upoważnieni użytkownicy, którzy mają hasło, mogą uzyskać dostęp do API, chociaż jeśli są programistami debugującymi aplikację, mogą uzyskać do niej bezpośredni dostęp w celach testowych.
Teraz, aby używać twojego API, muszą najpierw pobrać klienta i faktycznie uruchomić go w przeglądarce. Dopiero po pomyślnym odebraniu wywołania zwrotnego, a następnie wpisie użytkownika w krótkim czasie, API będzie akceptować wywołania.
Nie musisz się więc martwić, że może to być nieautoryzowany użytkownik bez poświadczeń.
(Tytuł pytania „Jak zabezpieczyć wywołania REST API” iz większości z tego, co mówisz, jest Twoim głównym zmartwieniem, a nie dosłownym pytaniem, JAK nazywa się twoje API, ale raczej KOGO, prawda? )
źródło
Ustaw SESSION var na serwerze, gdy klient po raz pierwszy ładuje twój
index.html
(lubbackbone.js
itp.)Sprawdź tę zmienną po stronie serwera przy każdym wywołaniu interfejsu API.
PS to nie jest rozwiązanie "zabezpieczające" !!! Ma to na celu ułatwienie obciążenia serwera, aby ludzie nie nadużyli go ani nie „łączyli” interfejsu API z innymi witrynami i aplikacjami.
źródło
Oto co robię:
Zabezpiecz API za pomocą nagłówka HTTP z wywołaniami takimi jak X-APITOKEN:
Użyj zmiennych sesji w PHP. Przygotuj system logowania i zapisz token użytkownika w zmiennych sesji.
Wywołaj kod JS za pomocą Ajax do PHP i użyj zmiennej sesji z curl, aby wywołać API. W ten sposób, jeśli zmienna sesji nie jest ustawiona, nie zostanie wywołana, a kod PHP zawiera token dostępu do API.
źródło