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.
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_dotenvaplikacja = 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 obiektuklasaUż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.
- The ratować metoda zapisuje nowy dokument użytkownika z podaną nazwą użytkownika i hasłem do kolekcji MongoDB i zwraca identyfikator wstawionego dokumentu.
- 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
- 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 ospokzarejestrowane_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})
- Zaimplementuj funkcjonalność logowania, aby obsłużyć proces uwierzytelniania i zweryfikować dane uwierzytelniające użytkownika. Pod trasą rejestracji dodaj następujący kod.
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ć.@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'})
- 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.
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.poktoken_wymagany(F):
@okłady (f)
pokozdobiony(*argumenty, **kwargi):
token = żądanie.cookies.get('znak')Jeślinie znak:
powrót jsonify({'wiadomość': Brak żetonu!}), 401pró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!'}), 401powrót f (bieżący_użytkownik, *argumenty, **kwargi)
powrót ozdobiony
- 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.