Główne logo strony
📅
🏷️FrontOps

Lokalizacja użytkownika

Na naszych stronach i aplikacjach webowych coraz częściej sięgamy po narzędzia, które pozwalają nam dowiedzieć się nieco więcej na temat odwiedzającego. Dzięki temu możemy zaproponować mu treści bądź funkcjonalności, które będą dużo bardziej spersonalizowane. Dość popularną techniką z tym związaną jest lokalizacja użytkownika. W tym krótkim artykule omówimy sobie dwa najpopularniejsze sposoby na to, aby dowiedzieć się skąd „klikają” osoby odwiedzające naszą stronę / aplikację.

Geolocation API

Pierwszym rozwiązaniem, które zapewne przychodzi nam do głowy, jest skorzystanie z geolokalizacji, którą mamy do dyspozycji w przeglądarce użytkownika. Jest to natywne rozwiązanie, dzięki któremu nie musimy korzystać z żadnych zewnętrznych bibliotek lub usług. W rezultacie otrzymamy współrzędne geograficzne pod którymi (według przeglądarki) znajduje się przeglądający naszą stronę.

W celu określenia lokalizacji przeglądarka będzie korzystała z takich danych jak sygnał GPS, dane operatorów komunikacyjnych, adres IP, dane z sieci Bluetooth i WiFi. Widzimy więc, że dokładność takiego pomiaru będzie w dużej mierze zależna od urządzenia, na którym nasza strona będzie przeglądana i od tego, jak wiele pozwoleń przyznał użytkownik swojej przeglądarce.

Lokalizacja użytkownika będzie również możliwa tylko w przypadku, gdy przeglądający udzieli na to zgody również już bezpośrednio na stronie. W przeciwnym razie Geolocation API nie zwróci nam żadnych danych. Co więcej, gdy użytkownik raz zdecyduje się odmówić dostępu do swoich danych lokalizacyjnych, przy ponownym odwiedzeniu naszej strony nie zostanie o to ponownie zapytany. Przeglądarka zapamięta jego wybór i zablokuje nam dostęp do API.

Mówiąc o danych, te nie są jakieś bardzo wyczerpujące – najważniejszymi danymi, jakie otrzymamy od przeglądarki, będą współrzędne geograficzne:

/* Przykładowy obiekt zwracany przez Geolocation API: */
{
    "altitude": null, // wysokość nad poziomem morza
    "altitudeAccuracy": null,  // dokładność pomiaru wysokości nad poz. morza w metrach
    "heading": null, // kierunek (w stopniach), w którym zwrócone jest urządzenie (0 = północ, 90 = wschód itd.)
    "latitude": 52.5884591, // szerokość geograficzna
    "longitude": 21.7366616, // wysokość geograficzna
    "accuracy": 2741, // dokładność pomiaru wysokości/szerokości geogr. wyrażona w metrach
    "speed": null // szybkość urządzenia wyrażona w m/s
}

Samo posiadanie powyższych danych nie daje nam zbyt wielu opcji. Prawdopodobnie w dalszym ciągu będziemy musieli skorzystać z jakiegoś zewnętrznego serwisu, który przetłumaczy nam współrzędne na nazwę kraju, miasta, adres itp.

Dane lokalizacyjne możemy pobierać na dwa sposoby – jednorazowo oraz ciągły nasłuch na zmianę lokalizacji:

const onSuccess = (pos) => console.log(pos);
const onError = (err) => console.log(err);
 
if (!navigator.geolocation) {
  alert("Geolocation is not supported by your browser");
} else {
  /* Jednorazowe pobranie danych. Funkcja "onSuccess" wykona się tylko raz. */
  navigator.geolocation.getCurrentPosition(onSuccess, onError);
 
  /* Nasłuch na zmianę lokalizacji. Funkcja "onSuccess" wykona się
  przy każdej zmianie pozycji. */
  navigator.geolocation.watchPosition(onSuccess, onError);
}

Podmiana lokalizacji

Kolejnym problemem, który posiadamy w przypadku lokalizacja użytkownika za pomocą Geolocation API jest fakt, iż możemy bardzo łatwo oszukać przeglądarkę i zmienić naszą pozycję jedynie za pomocą DevTools. Poniższy materiał pokazuje, w jaki sposób możemy to osiągnąć:

Widzimy więc, iż lokalizacja użytkownika za pomocą Geolocation API jest z jednej strony dość łatwa (wystarczy jedynie kilka linijek kodu JavaScript), jednak jest to metoda bardzo zawodna i nie powinniśmy opierać na niej głównych funkcjonalności naszych stron i aplikacji.

IP Lookup

Kolejnym sposobem na lokalizację użytkownika może być tzw. „IP Lookup”, czyli określanie pozycji jedynie za pomocą adresu IP. Jest sposób, z którego nie możemy skorzystać bezpośrednio w naszej aplikacji frontowej, ponieważ za pomocą JavaScript nie jesteśmy w stanie poznać adresu IP przeglądającego stronę.

Adres ten możemy odczytać z nagłówków HTTP zapytań sieciowych, a więc głównie na backend-owej części naszej aplikacji. Na tej właśnie zasadzie działają usługi, które oferują nam geolokalizacje użytkownika na podstawie jego adresu IP. W kodzie naszej aplikacji wykonujemy request pod wskazany adres (w requeście będzie adres IP przeglądającego) i w odpowiedzi otrzymujemy wszystkie informacje, jakie była w stanie określić używana przez nas usługa.

Oczywiście zadziała to poprawnie wtedy, gdy request będzie wykonany z przeglądarki użytkownika. W przypadku generowania stron za pomocą SSR adresem IP w nagłówku będzie adres naszego serwera, ale niemal każdy dostawca usługi IP Lookup pozwala na przesłanie dowolnego adresu IP jako jeden z parametrów zapytania sieciowego. Wtedy adres z nagłówka jest pomijany i użyty zostanie ten, który sami zdefiniujemy.

W pierwszej chwili może więc wydawać się bezsensowne korzystanie z usług IP Lookup po stronie serwerowej, jednakże należy pamiętać o tym, iż usługi te są zazwyczaj płatne. Najpopularniejszą metodą weryfikacji tego, czy możemy skorzystać z danego API, jest umieszczenie w requeście klucza API. To na jego podstawie dostawca usługi stwierdza, czy takie zapytanie w ogóle będzie obsłużone. Wszystkie zapytania sieciowe możemy podejrzeć w zakładce „Network” DevToolsów, więc nawet jeżeli klucz nie będzie znajdował się jawnie w kodzie (np. będzie odczytywany ze zmiennych środowiskowych), to i tak bez problemu będzie można podejrzeć go w DevTools.

Prawdopodobnie część dostawców usług typu „IP Lookup” będzie oferowało nam możliwość ustawienie domeny, spod której będą akceptowane zapytania, jednakże nie będzie to regułą i tego typu informacji jak klucze API lepiej nie pokazywać publicznie.

Lepszym rozwiązaniem w tym przypadku będzie wykonywanie zapytań z naszego serwera i przekazywanie na front danych zwróconych przez usługodawcę. W takim przypadku w pierwszej kolejności samodzielnie odczytujemy adres IP z requestu przychodzącego na nasz serwer i następnie wykonujemy kolejne zapytanie pod usługę IP Lookup podając odczytany przez nas adres.

Nasz… serwer… 😨

Blog poświęcony frontendowi a tutaj mowa o samodzielnym stawianiu serwera i obsłudze zapytań? Kilka lat temu byłby to pewien problem dla frontendowców – czekałoby nas pewnie stawianie jakiegoś serwera w Node.js bądź korzystanie z usług typu AWS Lambda, jednak na szczęście dzisiaj możemy zrealizować SSR dosyć prosto za pomocą Next.js. Nie będę tutaj rozwodził się nad tym, w jaki sposób to zrobić (tym bardziej że Next.js jest jedynie jedną z kilku opcji, czytelnik tego posta może zdecydować się na zupełnie inne podejście), ale na samym końcu tego wpisu podam link do mini projektu, w którym porównałem wszystkie opisane tutaj metody lokalizacji użytkownika.

Przykładowi dostawcy usług IP Lookup

W poniższej tabeli zebrałem kilku najbardziej popularnych dostawców usług typu IP Lookup. Są to dostawcy, którzy najczęściej byli polecani w przejrzanych przeze mnie postach na StackOverflow oraz innych blogach. Każdy z nich oferują pewną darmową liczbę requestów, dzięki czemu możemy spokojnie to przetestować a w przypadku mniejszych, pobocznych projektów być może limity te nie zostaną nawet przekroczone.

Pamiętajmy o tym, że adres IP nie jest również całkowicie wiarygodnym źródłem danych o użytkowniku. Może on zostać dość łatwo podmieniony poprzez używanie serwerów proxy bądź VPN. Zdecydowana większość użytkowników Internetu jednak nie korzysta z takich rozwiązań, więc z całkiem sporym prawdopodobieństwem możemy założyć, iż lokalizacja użytkownika w tym przypadku będzie dość wiarygodna.

Nazwa usługiDarmowy limit
ipapi1.000 zapytań / miesiąc.
ip-apiBrak limitu miesięcznego, maksymalnie 45 zapytań na minutę z jednego adresu adresu IP. Nie jest wymagana rejestracja i podawanie klucza API. Wersja darmowa może być użyta tylko w projektach niekomercyjnych.
ipregistry10.000 zapytań / miesiąc.
ipify1.000 zapytań / miesiąc.
ipgeolocation30.000 zapytań / miesiąc ale z limitem 1.000 zapytań / dzień. Wersja darmowa może być użyta tylko w projektach niekomercyjnych.
abstractapi20.000 zapytań / miesiąc.
ipwhois10.000 zapytań / miesiąc. Nie jest wymagana rejestracja i podawanie klucza API.
ipstack5.000 zapytań / miesiąc.
ipinfo50.000 zapytań / miesiąc.

Porównanie zwracanych danych 📊

Każdy z powyższych dostawców będzie na sobie tylko znany sposób próbował określić lokalizację użytkownika. Każdy z nich będzie również zwracał nam różne zestawy danych. Wszyscy powyższe serwisy (oraz Geolocation API) zostały przeze mnie porównane na jednej stronie. Dzięki temu możemy szybko sobie sprawdzić jakie dane na nasz temat oferują poszczególni usługodawcy, a także nasza przeglądarka.

Strona ta została zrealizowana za pomocą Next.js a link do wersji online oraz do repozytorium znajdują się poniżej:

Podsumowanie

Współczesny rozwój technologii pozwala na stosowanie coraz bardziej zaawansowanych i spersonalizowanych rozwiązań w naszych stronach i aplikacjach. Jednym z kluczowych elementów takiej personalizacji jest lokalizacja użytkownika, którą możemy uzyskać na wiele różnych sposobów.

Pierwszym z nich jest Geolocation API, natywne narzędzie dostępne w przeglądarce użytkownika, które jednak ma pewne ograniczenia. Działa na podstawie wielu źródeł danych, ale jego efektywność zależy od wielu czynników, w tym od zgody użytkownika na udostępnienie swojej lokalizacji.

Drugą metodą jest IP Lookup, technika polegająca na określaniu lokalizacji użytkownika za pomocą jego adresu IP. Jest to metoda bardziej niezawodna, ale wymaga korzystania z zewnętrznych usług i nie jest dostępna bezpośrednio w aplikacji frontowej.

Każda z tych technik ma swoje zalety i wady, a wybór między nimi zależy od specyfiki projektu i wymagań stawianych przed aplikacją. Warto pamiętać, że żadne z tych rozwiązań nie jest doskonałe i nie zawsze jest w 100% wiarygodne, ale mimo to stanowią one ważne narzędzie w tworzeniu spersonalizowanych doświadczeń dla użytkowników naszych stron i aplikacji.

Masz uwagi lub sugestie do tego wpisu?

discord iconPrzejdź na Discord