Webové tokeny JSON se snadno používají a ladí, ale nabízejí také působivé zvýšení zabezpečení.
Poškozená autentizace je i nadále trvalou zranitelností moderních webových aplikací – stále patří mezi 10 hlavních bezpečnostních rizik API OWASP.
Účinky této zranitelnosti mohou být vážné. Mohou udělit neoprávněný přístup k citlivým datům a ohrozit integritu systému. Chcete-li efektivně zajistit bezpečný přístup k aplikacím a jejich prostředkům, je důležité, abyste používali robustní mechanismy ověřování.
Zjistěte, jak můžete implementovat ověřování uživatelů ve Flasku pomocí JSON Web Tokens (JWT), oblíbené a efektivní metody založené na tokenech.
Autentizace na základě tokenů pomocí webových tokenů JSON
Autentizace založená na tokenech používá k ověření a autorizaci přístupu k systému nebo prostředku zašifrovaný řetězec znaků. Tento typ ověřování můžete implementovat pomocí různých metod, včetně tokenů relace, klíčů API a webových tokenů JSON.
Zejména JWT nabízejí bezpečný a kompaktní přístup pro přenos požadovaných uživatelských pověření mezi aplikacemi na straně klienta a servery.
JWT se skládá ze tří hlavních součástí: hlavičky, užitečného zatížení a podpisu. Záhlaví obsahuje metadata o tokenu, včetně hashovacího algoritmu použitého ke kódování tokenu.
Užitná část obsahuje skutečné přihlašovací údaje uživatele, jako je ID uživatele a oprávnění. Konečně podpis zajišťuje platnost tokenu ověřením jeho obsahu pomocí tajného klíče.
Pomocí JWT můžete ověřovat uživatele a ukládat data relace, to vše v rámci samotného tokenu.
Nastavte projekt Flask a databázi MongoDB
Chcete-li začít, vytvořte nový adresář projektu pomocí terminálu:
mkdir baňkový projekt
cd baňka-projekt
Dále nainstalujte virtualenv, k vytvoření místního virtuálního vývojového prostředí pro váš projekt Flask.
virtualenv venv
Nakonec aktivujte virtuální prostředí.
# Unix nebo MacOS:
zdroj venv/bin/activate
# Okna:
.\venv\Scripts\activate
Zde najdete kód tohoto projektu úložiště GitHub.
Nainstalujte požadované balíčky
V kořenovém adresáři složky projektu vytvořte nový požadavky.txt soubor a přidejte tyto závislosti pro projekt:
baňka
pyjwt
python-dotenv
pymongo
bcrypt
Nakonec spusťte níže uvedený příkaz a nainstalujte balíčky. Ujistěte se, že máte pip (správce balíčků) nainstalován; Pokud ne, nainstalujte jej do systému Windows, Mac nebo Linux.
pip install -r požadavky.txt
Vytvořte databázi MongoDB
Pokračujte a vytvořte databázi MongoDB. Můžeš nastavit místní databázi MongoDB, případně, vytvořte cluster na MongoDB Atlas, cloudové službě MongoDB.
Po vytvoření databáze zkopírujte identifikátor URI připojení, vytvořte a .env soubor v kořenovém adresáři vašeho projektu a přidejte jej následovně:
MONGO_URI=""
Nakonec nakonfigurujte připojení k databázi z aplikace Flask. Vytvoř nový utils/db.py soubor v kořenovém adresáři vašeho projektu s tímto kódem:
z pymongo import MongoClient
defconnect_to_mongodb(mongo_uri):
klient = MongoClient (mongo_uri)
db = client.get_database("uživatelé")
vrátit se db
Tato funkce naváže připojení k databázi MongoDB pomocí poskytnutého identifikátoru URI připojení. Poté vytvoří nový uživatelů kolekce, pokud neexistuje, a vrátí odpovídající instanci databáze.
Vytvořte webový server Flask
S nakonfigurovanou databází pokračujte a vytvořte soubor app.py soubor v kořenovém adresáři složky projektu a přidáním následujícího kódu vytvořte instanci aplikace Flask.
z baňka import Baňka
z routes.user_auth import registr_tras
z utils.db import connect_to_mongodb
import os
z dotenv import load_dotenvapp = Flask (__name__)
load_dotenv()mongo_uri = os.getenv(„MONGO_URI“)
db = connect_to_mongodb (mongo_uri)register_routes (aplikace, db)
-li __jméno__ == '__hlavní__':
app.run (debug=Skutečný)
Vytvořte koncové body Authentication API Endpoints
Pro implementaci autentizace uživatele ve vaší aplikaci Flask je zásadní definovat nezbytné koncové body API, které zpracovávají operace související s autentizací.
Nejprve však definujte model pro data uživatelů. Chcete-li tak učinit, vytvořte nový model/user_model.py soubor v kořenovém adresáři a přidejte následující kód.
z pymongo.kolekce import Sbírka
z bson.objectid import ObjectIdtřídaUživatel:
def__init__(self, kolekce: Collection, uživatelské jméno: str, heslo: str):
self.sběr = sběr
self.username = uživatelské jméno
self.password = heslo
defUložit(já):
uživatelská_data = {
'uživatelské jméno': vlastní uživatelské jméno,
'Heslo': vlastní.heslo
}
výsledek = self.collection.insert_one (user_data)
vrátit se str (result.inserted_id)@statická metoda
deffind_by_id(kolekce: Collection, user_id: str):
vrátit se collection.find_one({'_id': ObjectId (user_id)})
@statická metoda
deffind_by_username(kolekce: Collection, uživatelské jméno: str):
vrátit se collection.find_one({'uživatelské jméno': uživatelské jméno})
Výše uvedený kód specifikuje a Uživatel třída, která slouží jako datový model a definuje několik metod pro interakci s kolekcí MongoDB za účelem provádění operací souvisejících s uživatelem.
- The Uložit metoda uloží nový uživatelský dokument se zadaným uživatelským jménem a heslem do kolekce MongoDB a vrátí ID vloženého dokumentu.
- The find_by_id a find_by_username metody načítají uživatelské dokumenty z kolekce na základě poskytnutého ID uživatele nebo uživatelského jména.
Definujte autentizační cesty
- Začněme definováním registrační cesty. Tato trasa přidá nová uživatelská data do kolekce uživatelů MongoDB. V kořenovém adresáři vytvořte nový routes/user_auth.py soubor a následující kód.
import jwt
z functools import zábaly
z baňka import jsonify, request, make_response
z modely.uživatelský_model import Uživatel
import bcrypt
import osdefregistr_tras(aplikace, db):
kolekce = db.users
app.config['TAJNÝ KLÍČ'] = os.urandom(24)@app.route('/api/register', methods=['POST'])
defRegistrovat():
uživatelské jméno = request.json.get('uživatelské jméno')
heslo = request.json.get('Heslo')
existující_uživatel = User.find_by_username (kolekce, uživatelské jméno)
-li existující uživatel:
vrátit se jsonify({'zpráva': 'Uživatelské jméno již existuje!'})
hash_password = bcrypt.hashpw (password.encode('utf-8'), bcrypt.gensalt())
new_user = Uživatel (kolekce, uživatelské jméno, hashované_heslo.decode('utf-8'))
user_id = new_user.save()vrátit se jsonify({'zpráva': 'Uživatel se úspěšně zaregistroval!', 'uživatelské ID': uživatelské ID})
- Implementujte funkci přihlášení, abyste zvládli proces ověřování a ověřili přihlašovací údaje uživatele. Pod registrační cestou přidejte následující kód.
Přihlašovací koncový bod dělá dvě věci: ověřuje zadaná uživatelská pověření a po úspěšné autentizaci vygeneruje pro tohoto uživatele jedinečný JWT. Nastaví tento token jako soubor cookie v odpovědi spolu s datovou částí JSON označující úspěšné přihlášení. Pokud jsou přihlašovací údaje neplatné, vrátí odpověď JSON, která to potvrdí.@app.route('/api/login', methods=['POST'])
defpřihlásit se():
uživatelské jméno = request.json.get('uživatelské jméno')
heslo = request.json.get('Heslo')
uživatel = User.find_by_username (kolekce, uživatelské jméno)
-li uživatel:
-li bcrypt.checkpw (password.encode('utf-8'), uživatel['Heslo'].zakódovat('utf-8')):
token = jwt.encode({'uživatelské ID': str (uživatel['_id'])}, app.config['TAJNÝ KLÍČ'], algoritmus='HS256')
odpověď = make_response (jsonify({'zpráva': 'Přihlášení úspěšné!'}))
response.set_cookie('žeton', token)
vrátit se Odezvavrátit se jsonify({'zpráva': 'Neplatné uživatelské jméno nebo heslo'})
- Definujte funkci dekorátoru, která ověřuje webové tokeny JSON (JWT) předané spolu s následnými požadavky API. Přidejte kód níže do registr_tras blok funkčního kódu.
Tato funkce dekorátoru zajišťuje přítomnost platného tokenu JWT v následných požadavcích API. Zkontroluje, zda token chybí, nevypršela jeho platnost nebo je platný, a pokud ano, vrátí příslušnou odpověď JSON.deftoken_required(F):
@wraps (f)
defzdobené(*args, **kwargs):
token = request.cookies.get('žeton')-line žeton:
vrátit se jsonify({'zpráva': "Chybí token!"}), 401Snaž se:
data = jwt.decode (token, app.config['TAJNÝ KLÍČ'], algoritmy=['HS256'])
current_user = User.find_by_id (sbírka, data['uživatelské ID'])
až na jwt. ExpiredSignatureError:
vrátit se jsonify({'zpráva': "Platnost tokenu vypršela!"}), 401
až na jwt. InvalidTokenError:
vrátit se jsonify({'zpráva': "Neplatný token!"}), 401vrátit se f (aktuální_uživatel, *args, **kwargs)
vrátit se zdobené
- Nakonec vytvořte chráněnou trasu.
@app.route('/api/users', methods=['GET'])
@token_required
defget_users(současný uživatel):
uživatelé = seznam (collection.find({}, {'_id': 0}))
vrátit se jsonify (uživatelé)
Tento koncový bod zpracovává logiku pro načítání uživatelských dat z databáze, ale vyžaduje, aby klient odesílající požadavky zahrnul platný token pro přístup k datům.
Nakonec spusťte níže uvedený příkaz a roztočte vývojový server.
baňka běží
Chcete-li otestovat registraci, přihlášení a koncový bod chráněných uživatelů, můžete použít Postman nebo jiného klienta API. Žádosti zasílejte na http://localhost: 5000/api/a sledujte odpovědi, abyste ověřili funkčnost těchto koncových bodů API.
Je ověřování tokenů spolehlivým bezpečnostním opatřením?
Webové tokeny JSON poskytují robustní a efektivní způsob ověřování uživatelů pro vaši webovou aplikaci. Je však důležité pochopit, že autentizace pomocí tokenu není spolehlivá; je to jen jeden díl větší bezpečnostní skládačky.
Kombinujte autentizaci pomocí tokenu s dalšími osvědčenými postupy zabezpečení. Nezapomeňte neustále monitorovat a přijmout konzistentní bezpečnostní postupy; výrazně zvýšíte celkovou bezpečnost vašich aplikací Flask.