Tokeny sieciowe JSON są łatwe w użyciu i debugowaniu, ale oferują również imponujący wzrost bezpieczeństwa.

Uszkodzone uwierzytelnianie nadal stanowi uporczywą lukę w nowoczesnych aplikacjach internetowych — nadal zajmuje wysokie miejsce w pierwszej dziesiątce zagrożeń bezpieczeństwa interfejsu API OWASP.

Skutki tej luki w zabezpieczeniach mogą być poważne. Mogą udzielić nieautoryzowanego dostępu do poufnych danych i naruszyć integralność systemu. Aby skutecznie zapewnić bezpieczny dostęp do aplikacji i ich zasobów, konieczne jest stosowanie niezawodnych mechanizmów uwierzytelniania.

Dowiedz się, jak zaimplementować uwierzytelnianie użytkownika w Flask przy użyciu JSON Web Tokens (JWT), popularnej i skutecznej metody opartej na tokenach.

Uwierzytelnianie oparte na tokenach przy użyciu tokenów internetowych JSON

Uwierzytelnianie oparte na tokenie wykorzystuje zaszyfrowany ciąg znaków do sprawdzania poprawności i autoryzacji dostępu do systemu lub zasobu. Możesz zaimplementować ten typ uwierzytelniania przy użyciu różnych metod, w tym tokenów sesji, kluczy API i tokenów internetowych JSON.

instagram viewer

W szczególności tokeny JWT oferują bezpieczne i kompaktowe podejście do przesyłania wymaganych poświadczeń użytkowników między aplikacjami po stronie klienta a serwerami.

JWT składa się z trzech głównych komponentów: nagłówka, ładunku i podpisu. Nagłówek zawiera metadane dotyczące tokena, w tym algorytm mieszania używany do kodowania tokena.

Ładunek zawiera rzeczywiste poświadczenia użytkownika, takie jak identyfikator użytkownika i uprawnienia. Wreszcie podpis zapewnia ważność tokena, weryfikując jego zawartość za pomocą tajnego klucza.

Korzystając z JWT, możesz uwierzytelniać użytkowników i przechowywać dane sesji w samym tokenie.

Skonfiguruj projekt Flask i bazę danych MongoDB

Aby rozpocząć, utwórz nowy katalog projektu za pomocą terminala:

projekt kolby mkdir
projekt kolby cd

Następnie zainstaluj wirtualna, aby utworzyć lokalne wirtualne środowisko programistyczne dla projektu Flask.

wirtualna wartość venv

Na koniec aktywuj środowisko wirtualne.

# Unix lub MacOS: 
źródło venv/bin/aktywuj

# Okna:
.\venv\Scripts\aktywacja

Możesz znaleźć kod tego projektu w this Repozytorium GitHub.

Zainstaluj wymagane pakiety

W katalogu głównym folderu projektu utwórz nowy wymagania.txt plik i dodaj te zależności dla projektu:

kolba
pyjwt
python-dotenv
pymongo
bcrypt

Na koniec uruchom poniższe polecenie, aby zainstalować pakiety. Upewnij się że masz pypeć (menedżer pakietów) zainstalowany; Jeśli nie, zainstaluj go w systemie Windows, Mac lub Linux.

pip install -r wymagania.txt

Utwórz bazę danych MongoDB

Śmiało utwórz bazę danych MongoDB. Możesz skonfiguruj lokalną bazę danych MongoDB, alternatywnie, utwórz klaster w MongoDB Atlas, opartej na chmurze usłudze MongoDB.

Po utworzeniu bazy danych skopiuj identyfikator URI połączenia, utwórz plik .env plik w katalogu głównym projektu i dodaj go w następujący sposób:

MONGO_URI=""

Na koniec skonfiguruj połączenie z bazą danych z aplikacji Flask. Stwórz nowy utils/db.py plik w katalogu głównym twojego projektu, z tym kodem:

z pymongo import Klient Mongo

pokconnect_to_mongodb(mongo_uri):
klient = MongoClient (mongo_uri)
db = klient.get_database(„użytkownicy”)
powrót baza danych

Ta funkcja nawiązuje połączenie z bazą danych MongoDB przy użyciu podanego identyfikatora URI połączenia. Następnie tworzy nowy użytkownicy collection, jeśli nie istnieje, i zwraca odpowiednią instancję bazy danych.

Utwórz serwer WWW Flask

Po skonfigurowaniu bazy danych śmiało utwórz plik aplikacja.py plik w katalogu głównym folderu projektu i dodaj następujący kod, aby utworzyć instancję aplikacji Flask.

z kolba import Kolba
z trasy.uwierzytelnianie_użytkownika import zarejestrowane_trasy
z utils.db import connect_to_mongodb
import os
z dotenv import ładuj_dotenv

aplikacja = Kolba (__nazwa__)
load_dotenv()

mongo_uri = os.pobierz(„MONGO_URI”)
db = connect_to_mongodb (mongo_uri)

register_routes (aplikacja, baza danych)

Jeśli __nazwa__ == '__główny__':
app.run (debugowanie=PRAWDA)

Utwórz punkty końcowe interfejsu API uwierzytelniania

Aby zaimplementować uwierzytelnianie użytkownika w aplikacji Flask, kluczowe jest zdefiniowanie niezbędnych punktów końcowych API, które obsługują operacje związane z uwierzytelnianiem.

Najpierw jednak zdefiniuj model danych użytkowników. W tym celu utwórz nowy model/user_model.py plik w katalogu głównym i dodaj następujący kod.

z pymongo.kolekcja import Kolekcja
z bson.identyfikator obiektu import Identyfikator obiektu

klasaUżytkownik:
pok__w tym__(self, kolekcja: Kolekcja, nazwa użytkownika: str, hasło: str):
samo.kolekcja = kolekcja
nazwa.użytkownika = nazwa użytkownika
hasło.własne = hasło
pokratować(samego siebie):
dane_użytkownika = {
'nazwa użytkownika': własna.nazwa użytkownika,
'hasło': własne.hasło
}
wynik = self.collection.insert_one (dane_użytkownika)
powrót str (wynik.wstawiony_id)

@metoda statyczna
pokznajdź_by_id(kolekcja: Kolekcja, user_id: str):
powrót kolekcja.znajdź_jeden({'_ID': Identyfikator obiektu (identyfikator_użytkownika)})

@metoda statyczna
pokznajdź_przez_nazwę_użytkownika(kolekcja: Kolekcja, nazwa użytkownika: str):
powrót kolekcja.znajdź_jeden({'nazwa użytkownika': nazwa użytkownika})

Powyższy kod określa a Użytkownik klasa, która służy jako model danych i definiuje kilka metod interakcji z kolekcją MongoDB w celu wykonywania operacji związanych z użytkownikiem.

  1. The ratować metoda zapisuje nowy dokument użytkownika z podaną nazwą użytkownika i hasłem do kolekcji MongoDB i zwraca identyfikator wstawionego dokumentu.
  2. The znajdź_by_id I znajdź_przez_nazwę_użytkownika metody pobierają dokumenty użytkownika z kolekcji na podstawie odpowiednio podanego identyfikatora użytkownika lub nazwy użytkownika.

Zdefiniuj trasy uwierzytelniania

  1. Zacznijmy od zdefiniowania trasy rejestracji. Ta trasa doda nowe dane użytkownika do kolekcji użytkowników MongoDB. W katalogu głównym utwórz nowy trasy/user_auth.py plik i następujący kod.
    import jwt
    z funtools import okłady
    z kolba import jsonify, żądanie, make_response
    z modele.model_użytkownika import Użytkownik
    import bcrypt
    import os

    pokzarejestrowane_trasy(aplikacja, baza danych):
    kolekcja = db.użytkownicy
    aplikacja.konfiguracja['SEKRETNY KLUCZ'] = os.urandom(24)

    @app.route('/api/register', metody=['POST'])
    pokrejestr():

    nazwa użytkownika = żądanie.json.get('nazwa użytkownika')
    hasło = żądanie.json.get('hasło')

    istniejący_użytkownik = User.find_by_username (kolekcja, nazwa użytkownika)
    Jeśli istniejący użytkownik:
    powrót jsonify({'wiadomość': 'Nazwa użytkownika już istnieje!'})

    hashed_password = bcrypt.hashpw (hasło.encode('utf-8'), bcrypt.gensalt())
    nowy_użytkownik = Użytkownik (kolekcja, nazwa użytkownika, hashed_password.decode('utf-8'))
    user_id = new_user.save()

    powrót jsonify({'wiadomość': 'Użytkownik zarejestrował się pomyślnie!', 'identyfikator użytkownika': identyfikator użytkownika})

  2. Zaimplementuj funkcjonalność logowania, aby obsłużyć proces uwierzytelniania i zweryfikować dane uwierzytelniające użytkownika. Pod trasą rejestracji dodaj następujący kod.
     @app.route('/api/login', metody=['POST'])
    pokZaloguj sie():
    nazwa użytkownika = żądanie.json.get('nazwa użytkownika')
    hasło = żądanie.json.get('hasło')
    user = User.find_by_username (kolekcja, nazwa użytkownika)
    Jeśli użytkownik:
    Jeśli bcrypt.checkpw (hasło.encode('utf-8'), użytkownik['hasło'].kodować('utf-8')):
    token = jwt.encode({'identyfikator użytkownika': str (użytkownik['_ID'])}, aplikacja.config['SEKRETNY KLUCZ'], algorytm=„HS256”)

    odpowiedź = make_response (jsonify({'wiadomość': 'Logowanie zakończone sukcesem!'}))
    odpowiedź.set_cookie('znak', żeton)
    powrót odpowiedź

    powrót jsonify({'wiadomość': 'Nieprawidłowa nazwa użytkownika lub hasło'})

    Punkt końcowy logowania robi dwie rzeczy: weryfikuje podane poświadczenia użytkownika i po pomyślnym uwierzytelnieniu generuje dla tego użytkownika unikalny token JWT. Ustawia ten token jako plik cookie w odpowiedzi wraz z ładunkiem JSON wskazującym pomyślne logowanie. Jeśli poświadczenia są nieprawidłowe, zwróci odpowiedź JSON, aby to wskazać.
  3. Zdefiniuj funkcję dekoratora, która weryfikuje tokeny JSON Web Token (JWT) przekazywane wraz z kolejnymi żądaniami API. Dodaj poniższy kod w zarejestrowane_trasy blok kodu funkcji.
    poktoken_wymagany(F):
    @okłady (f)
    pokozdobiony(*argumenty, **kwargi):
    token = żądanie.cookies.get('znak')

    Jeślinie znak:
    powrót jsonify({'wiadomość': Brak żetonu!}), 401

    próbować:
    data = jwt.decode (token, app.config['SEKRETNY KLUCZ'], algorytmy=[„HS256”])
    current_user = User.find_by_id (kolekcja, dane['identyfikator użytkownika'])
    z wyjątkiem jwt. Błąd podpisu wygasłego:
    powrót jsonify({'wiadomość': „Token wygasł!”}), 401
    z wyjątkiem jwt. Błąd nieprawidłowego tokena:
    powrót jsonify({'wiadomość': 'Nieprawidłowy Token!'}), 401

    powrót f (bieżący_użytkownik, *argumenty, **kwargi)

    powrót ozdobiony

    Ta funkcja dekoratora zapewnia obecność prawidłowego tokena JWT w kolejnych żądaniach API. Sprawdza, czy brakuje tokena, wygasł lub jest ważny, i zwraca odpowiednią odpowiedź JSON, jeśli tak jest.
  4. Na koniec utwórz chronioną trasę.
     @app.route('/api/users', Methods=['GET'])
    @token_wymagany
    pokpobierz_użytkowników(aktualny użytkownik):
    użytkownicy = lista (kolekcja.znajdź({}, {'_ID': 0}))
    powrót jsonify (użytkownicy)

Ten punkt końcowy obsługuje logikę pobierania danych użytkownika z bazy danych, ale wymaga, aby klient wysyłający żądania zawierał prawidłowy token w celu uzyskania dostępu do danych.

Na koniec uruchom poniższe polecenie, aby przyspieszyć serwer programistyczny.

bieg kolby

Aby przetestować rejestrację, logowanie i punkt końcowy chronionych użytkowników, możesz użyć Postmana lub dowolnego innego klienta API. Wyślij prośby do http://localhost: 5000/api/i obserwuj odpowiedzi, aby zweryfikować funkcjonalność tych punktów końcowych API.

Czy uwierzytelnianie tokenem jest niezawodnym środkiem bezpieczeństwa?

JSON Web Tokens zapewniają solidny i skuteczny sposób uwierzytelniania użytkowników Twojej aplikacji internetowej. Jednak ważne jest, aby zrozumieć, że uwierzytelnianie tokenem nie jest niezawodne; to tylko jeden element większej układanki bezpieczeństwa.

Połącz uwierzytelnianie tokena z innymi najlepszymi praktykami w zakresie bezpieczeństwa. Pamiętaj o ciągłym monitorowaniu i stosowaniu spójnych praktyk bezpieczeństwa; znacznie poprawisz ogólne bezpieczeństwo swoich aplikacji Flask.