Integracja logowania przez zewnętrzne usługi, takie jak GitHub, jest jedną z najbardziej popularnych metod uwierzytelniania w aplikacjach internetowych. OAuth2 jest protokołem autoryzacji, który umożliwia aplikacjom uzyskiwanie dostępu do zasobów użytkownika w zewnętrznych serwisach, takich jak GitHub, bez konieczności udostępniania hasła. Implementacja OAuth2 w Twojej aplikacji może znacząco poprawić komfort użytkowników, dając im możliwość szybkiego logowania za pomocą jednego kliknięcia.
Aby zaimplementować logowanie z GitHub w aplikacji webowej, musisz przejść przez kilka kluczowych kroków, od rejestracji aplikacji na GitHubie, po wdrożenie odpowiednich endpointów w aplikacji. Poniżej przedstawiam szczegółowy proces konfiguracji i implementacji tego rozwiązania.
Na początku, wchodzimy na stronę swojego profilu na GitHubie i klikamy ikonę profilu w prawym górnym rogu. Następnie przechodzimy do Ustawień (Settings), a następnie Developer settings, OAuth Apps i klikamy "New OAuth App". W formularzu, który się pojawi, musisz wypełnić wymagane pola:
-
Nazwa aplikacji: Na przykład "SaasFastAPIapp".
-
URL strony głównej: To adres Twojej strony domowej SaaS, np.
http://localhost:8000/, który utworzysz później. -
URL przekierowania autoryzacji: Jest to endpoint Twojej aplikacji, który będzie wywoływany do odświeżenia tokenu. Możesz ustawić go na
http://localhost:8000/github/auth/token.
Po zarejestrowaniu aplikacji, otrzymasz dane takie jak client ID oraz client secret, które będą potrzebne do dalszej implementacji.
Z tymi informacjami przechodzimy do kodu naszej aplikacji. Tworzymy nowy moduł third_party_login.py, który będzie zawierał dane i funkcje pomocnicze do integracji z GitHubem:
Uwaga: W produkcji nigdy nie powinno się umieszczać danych takich jak identyfikator klienta (client ID) czy sekret klienta (client secret) bezpośrednio w kodzie źródłowym. Należy używać bezpiecznych metod przechowywania tych danych, np. zmiennych środowiskowych.
Kolejnym krokiem jest stworzenie funkcji pomocniczej resolve_github_token, która przetwarza token uzyskany po autoryzacji użytkownika i zwraca dane o użytkowniku:
W tej funkcji najpierw wysyłamy zapytanie do GitHub API, aby pobrać dane użytkownika na podstawie przekazanego tokenu. Następnie próbujemy znaleźć użytkownika w naszej bazie danych na podstawie loginu lub e-maila.
Kolejny krok to stworzenie endpointu, który pozwala na uzyskanie URL do logowania na GitHubie. W tym celu tworzymy nowy moduł github_login.py:
Endpoint /auth/url zwróci URL, na który użytkownik zostanie przekierowany, aby autoryzować dostęp do swojej aplikacji GitHub. Po autoryzacji GitHub przekieruje użytkownika z powrotem do naszej aplikacji, wywołując URL przekierowania, który wcześniej ustawiliśmy.
Teraz musimy dodać endpoint, który odbierze kod autoryzacji i wymieni go na token dostępu. W tym celu modyfikujemy moduł github_login.py:
W tym endpointcie wymieniamy kod autoryzacji na token dostępu, który następnie jest zwracany użytkownikowi.
Na koniec musimy zaimplementować endpoint, który pozwoli użytkownikowi zalogować się do aplikacji po autoryzacji za pomocą GitHub. Możemy to zrobić, dodając odpowiednią metodę w głównym pliku aplikacji main.py:
W tym miejscu aplikacja weryfikuje użytkownika, korzystając z tokenu, a następnie zwraca odpowiedź potwierdzającą, że użytkownik jest zalogowany.
Dodatkowe uwagi:
Warto pamiętać, że proces implementacji logowania przez GitHub przy użyciu OAuth2 nie ogranicza się tylko do opisanych kroków. Istnieją dodatkowe aspekty, które warto rozważyć przy implementacji takiego rozwiązania:
-
Bezpieczeństwo: Ważne jest, aby nie przechowywać danych wrażliwych, takich jak
client_idiclient_secret, w publicznie dostępnych miejscach kodu. Należy używać mechanizmów zarządzania sekretami. -
Zarządzanie sesjami: Po uzyskaniu tokenu dostępu użytkownik powinien zostać zapisany w systemie sesji lub tokenów, aby utrzymać jego stan zalogowania przez dłuższy czas.
-
Obsługa błędów: Należy zadbać o odpowiednią obsługę błędów, zwłaszcza w sytuacjach, gdy użytkownik nie udzieli zgody na dostęp do swojego konta na GitHubie lub token jest nieważny.
-
Dalsza integracja: Chociaż GitHub jest jednym z najpopularniejszych dostawców OAuth2, warto rozważyć implementację innych dostawców, takich jak Google czy Twitter. W każdym przypadku proces jest podobny, a różnice wynikają głównie z różnych parametrów konfiguracyjnych w aplikacji dostawcy.
-
Przekierowanie frontendowe: Proces przekierowania użytkownika na stronę GitHub i z powrotem do aplikacji jest obsługiwany przez frontend. Upewnij się, że masz odpowiednią konfigurację na stronie, aby użytkownik był płynnie przekierowywany po udanej autoryzacji.
Jak optymalizować zapytania SQL w aplikacjach?
Optymalizacja zapytań SQL to jedno z kluczowych zagadnień, z którym spotykają się programiści, zwłaszcza gdy pracują z dużymi zbiorami danych. Efektywność zapytań może znacząco wpłynąć na wydajność całej aplikacji. W tym kontekście warto zwrócić uwagę na kilka kluczowych zasad, które pozwolą uniknąć najczęstszych błędów i przyspieszyć działanie aplikacji.
Jednym z najczęstszych problemów w optymalizacji zapytań SQL jest tzw. problem N+1 zapytań. Dochodzi do niego, gdy aplikacja wykonuje zapytanie, aby pobrać listę elementów, a następnie w pętli wykonuje kolejne zapytania dla każdego elementu, co prowadzi do wielu niepotrzebnych operacji w bazie danych. Na przykład, jeśli chcemy pobrać wydarzenia wraz z powiązanymi sponsorami, początkowe zapytanie może wydobyć dane z tabeli wydarzeń, a następnie dla każdego wydarzenia wykonywane będzie dodatkowe zapytanie, aby pobrać sponsorów. Problem w tym, że w ten sposób wykonujemy N zapytań, co znacząco obciąża bazę danych.
Rozwiązaniem tego problemu jest tzw. eager loading (ładowanie danych z wyprzedzeniem). W SQLAlchemy, popularnym narzędziu do pracy z bazą danych w Pythonie, można zastosować funkcję joinedload, która pozwala na załadowanie powiązanych rekordów w ramach jednego zapytania. Dzięki temu zapytanie będzie wyglądać następująco:
Takie podejście eliminuje problem N+1 zapytań, ponieważ zamiast wykonywać oddzielne zapytania dla każdego wydarzenia, wszystkie powiązane dane są ładowane w ramach jednego zapytania.
Kolejnym zagadnieniem, które należy wziąć pod uwagę, jest użycie instrukcji JOIN. Stosowanie tej instrukcji może pomóc w uproszczeniu zapytania, jednak należy jej używać ostrożnie, aby nie przeciążyć zapytania zbędnymi połączeniami. Należy unikać dołączania tabel, które nie są bezpośrednio potrzebne w zapytaniu.
Załóżmy, że chcemy uzyskać listę sponsorów wraz z kwotą ich wkładu w dane wydarzenie, posortowaną od najwyższej do najniższej. Możemy użyć kilku złączeń, ponieważ potrzebujemy trzech tabel: sponsorów, sponsoringu i wydarzenia. Pierwsza wersja zapytania mogłaby wyglądać tak:
Jednak takie zapytanie włącza tabelę Event, której w rzeczywistości nie potrzebujemy, co może niepotrzebnie obciążyć bazę danych. Warto zoptymalizować zapytanie i pominąć tę tabelę:
Dzięki temu zapytanie jest bardziej efektywne, ponieważ nie angażuje zbędnych tabel i wykonuje tylko to, co jest naprawdę potrzebne.
Trzecią zasadą jest minimalizacja danych, które są pobierane z bazy. Pobieranie zbyt dużej ilości danych, szczególnie gdy nie są one wszystkie potrzebne, może znacznie spowolnić działanie aplikacji. Warto stosować funkcję load_only, która pozwala na załadowanie tylko wybranych kolumn, a nie całych rekordów. Przykładowo, jeśli chcemy uzyskać tylko identyfikatory biletów, użytkowników i ceny, możemy ograniczyć pobierane dane do tych trzech kolumn:
Takie podejście nie tylko poprawia wydajność zapytania, ale także zmniejsza zużycie pamięci, ponieważ nie musimy ładować wszystkich danych, które mogą być nieistotne w danym kontekście.
Optymalizacja zapytań SQL to jednak temat znacznie szerszy. Wybór odpowiedniej bazy danych jest kluczowy i zależy od specyficznych potrzeb aplikacji. Bazy danych różnią się pod względem architektury i funkcji, które oferują w zakresie optymalizacji zapytań. Niektóre bazy wspierają techniki takie jak partycjonowanie, replikacja, czy rozproszone przetwarzanie, co może poprawić skalowalność i dostępność danych. Warto również zwrócić uwagę na zaawansowane techniki optymalizacji zapytań, takie jak optymalizacja kosztów, przepisywanie zapytań, czy pamięć podręczna zapytań, które pozwalają zmniejszyć czas wykonania i zużycie zasobów.
Na koniec, ważne jest, aby podczas wyboru bazy danych przeprowadzić odpowiednie testy wydajnościowe, porównać jej cechy i ograniczenia, oraz dopasować do specyficznych wymagań aplikacji. Testowanie w realistycznych warunkach, z danymi podobnymi do tych, które będą używane w produkcji, pozwala na uzyskanie obiektywnych wyników i wybranie najefektywniejszej technologii.
Jak skutecznie maskować dane w MongoDB i zabezpieczać dane w bazach NoSQL?
Maskowanie danych to technika wykorzystywana w celu ukrycia wrażliwych informacji, które mogą zostać ujawnione stronie trzeciej, jak np. w ramach API. Jej celem jest zapewnienie, aby dane, które muszą być udostępnione do dalszej analizy lub przetwarzania, nie zawierały informacji osobowych (PII - Personally Identifiable Information) lub jakichkolwiek innych danych, których udostępnienie byłoby niepożądane lub naruszałoby przepisy prawa, np. RODO. W kontekście MongoDB i baz NoSQL, maskowanie danych staje się jednym z kluczowych elementów ochrony danych osobowych i prywatności użytkowników.
Załóżmy, że mamy aplikację opartą na FastAPI, która jest połączona z bazą danych MongoDB. W tym scenariuszu często zachodzi potrzeba udostępnienia danych użytkowników dla partnerów zewnętrznych, np. w celach marketingowych. W przypadku MongoDB operacje na danych są realizowane za pomocą tzw. pipelines, które pozwalają na przeprowadzanie operacji na danych w sposób etapowy i kontrolowany. Dzięki temu możemy łatwo maskować, modyfikować lub usuwać określone pola z dokumentów, zanim zostaną one przekazane użytkownikowi zewnętrznemu. Przykładem takich danych mogą być dane osobowe, jak imiona, adresy e-mail czy daty urodzenia użytkowników.
W procesie maskowania danych, pierwszym krokiem jest przygotowanie bazy danych i kolekcji z wrażliwymi informacjami. Załóżmy, że mamy kolekcję użytkowników, zawierającą dane takie jak: imię, adres e-mail, rok urodzenia, kraj, a także dane dotyczące akcji podejmowanych przez użytkowników, np. subskrypcji usług. Warto dodać, że dane te będą miały przypisaną zgodę użytkownika na ich udostępnienie – pole „consent_to_share_data”.
Pierwszym etapem jest zdefiniowanie tzw. „pipeline”, który będzie odpowiadał za ukrywanie lub modyfikowanie danych wrażliwych. Pipeline w MongoDB to zestaw operacji, które wykonujemy na zbiorze danych. Najpierw filtrujemy użytkowników, którzy wyrazili zgodę na udostępnianie swoich danych. Możemy to zrobić przy użyciu operacji $redact, która pozwala na warunkowe wykluczenie dokumentów, które nie spełniają określonych kryteriów. Na przykład, możemy wykluczyć wszystkich użytkowników, którzy nie wyrazili zgody na udostępnianie swoich danych, jak pokazuje poniższy kod:
Kolejnym krokiem jest usunięcie z dokumentów danych takich jak adres e-mail czy imię użytkownika, co możemy zrobić za pomocą operacji $unset. W ten sposób dane te zostaną całkowicie usunięte z wyników zapytania:
Następnie, aby uniemożliwić ujawnienie jakichkolwiek dat w formie rzeczywistej, możemy je zasłonić, zmieniając dzień w polu daty na fikcyjny ciąg znaków, np. "-XX". Operację tę realizujemy przy użyciu operacji $concat i $substrCP, aby zaktualizować pole daty w każdym z dokumentów:
Potem możemy zaktualizować cały zestaw działań użytkownika, stosując operację $map, która pozwoli na iterację przez pole „actions” i zastosowanie obfuscacji dla każdego z elementów listy:
Po przygotowaniu odpowiednich operacji w pipeline, możemy połączyć je w jeden zbiór, a następnie stworzyć widok na kolekcji użytkowników, który będzie zawierał tylko dane po zamaskowaniu:
W ten sposób uzyskujemy widok, w którym dane osobowe użytkowników zostały zabezpieczone przed ujawnieniem. Ostatecznym krokiem jest zdefiniowanie endpointu w aplikacji FastAPI, który udostępni ten widok zewnętrznemu konsumentowi, takim jak system analityczny czy partner biznesowy. Endpoint ten będzie w stanie zwrócić zamaskowane dane użytkowników bez ujawniania wrażliwych informacji, co gwarantuje bezpieczeństwo i zgodność z przepisami dotyczącymi ochrony danych osobowych:
Warto podkreślić, że sama technika maskowania danych nie jest wystarczająca, aby zapewnić pełną ochronę danych w systemie. Istnieje kilka innych metod zabezpieczania danych, które powinny być zastosowane równolegle. Wśród najistotniejszych są:
-
Szyfrowanie danych w spoczynku (encryption at rest) – zapewnia, że dane przechowywane w bazie danych będą zaszyfrowane, co uniemożliwia dostęp do nich osobom nieupoważnionym, nawet w przypadku fizycznego dostępu do dysków.
-
Szyfrowanie danych w tranzycie (encryption in transit) – zapewnia, że dane przesyłane pomiędzy serwerem aplikacji a bazą danych (lub innymi systemami) są zabezpieczone przed przechwyceniem przez osoby trzecie.
-
Kontrola dostępu oparta na rolach (RBAC) – pozwala na precyzyjne zarządzanie, kto ma dostęp do jakich danych. Dzięki implementacji RBAC można ograniczyć dostęp do wrażliwych informacji tylko do osób, które naprawdę muszą mieć do nich dostęp, zgodnie z ich rolą w organizacji.
Podsumowując, maskowanie danych w MongoDB to jedno z kluczowych narzędzi, które pozwala na udostępnianie danych w sposób bezpieczny i zgodny z przepisami ochrony danych osobowych. Jednakże pełne zabezpieczenie danych wymaga również zastosowania innych metod ochrony, takich jak szyfrowanie i kontrola dostępu.
Jak cieszyć się życiem, nie rezygnując z przyjemności: poradnik zdrowego stylu życia 2025
Jak poruszać się po mieście: Podstawowe zwroty i przydatne informacje
Jak przeprowadzić testy jednostkowe dla API i zaimplementować filtrację w FastAPI?
Jak przygotować ciasto czekoladowe z musem irlandzkim i ganachem czekoladowym: krok po kroku
Jak wielka katastrofa na końcu kredy zmieniła życie na Ziemi?
Jak poruszać się po mieście? Przewodnik po podstawowych zwrotach i słownictwie
Jak rozwój i modyfikacje Bitcoin wpłynęły na ekosystem kryptowalut?
Jakie niebezpieczeństwa faszyzmu wiążą się z populizmem autorytarnym w Stanach Zjednoczonych?
Jak przygotować dania z wędzonym makrelą i warzywami, zachowując smak i wartości odżywcze?
Jak zrozumieć ekstremizm politycznej poprawności, populizm i cechy wielkich liderów?

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский