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.

instagram viewer

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_dotenv

app = 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 ObjectId

tří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.

  1. 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.
  2. 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

  1. 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 os

    defregistr_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})

  2. 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.
     @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 Odezva

    vrátit se jsonify({'zpráva': 'Neplatné uživatelské jméno nebo heslo'})

    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í.
  3. 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.
    deftoken_required(F):
    @wraps (f)
    defzdobené(*args, **kwargs):
    token = request.cookies.get('žeton')

    -line žeton:
    vrátit se jsonify({'zpráva': "Chybí token!"}), 401

    Snaž 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!"}), 401

    vrátit se f (aktuální_uživatel, *args, **kwargs)

    vrátit se zdobené

    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.
  4. 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.