Tokenurile web JSON sunt ușor de utilizat și de depanat, dar oferă și un spor de securitate impresionant.
Autentificarea întreruptă continuă să fie o vulnerabilitate persistentă în aplicațiile web moderne – încă se clasează foarte bine în primele 10 riscuri de securitate API ale OWASP.
Efectele acestei vulnerabilități pot fi severe. Aceștia pot acorda acces neautorizat la date sensibile și pot compromite integritatea sistemului. Pentru a asigura în mod eficient accesul securizat la aplicații și resursele acestora, este vital să utilizați mecanisme de autentificare robuste.
Aflați cum puteți implementa autentificarea utilizatorilor în Flask folosind JSON Web Tokens (JWT), o metodă populară și eficientă bazată pe token.
Autentificare bazată pe jetoane folosind jetoane web JSON
Autentificarea bazată pe token folosește un șir criptat de caractere pentru a valida și autoriza accesul la un sistem sau o resursă. Puteți implementa acest tip de autentificare folosind diverse metode, inclusiv jetoane de sesiune, chei API și jetoane web JSON.
JWT-urile, în special, oferă o abordare sigură și compactă pentru transmiterea acreditărilor necesare utilizatorilor între aplicațiile și serverele de pe partea clientului.
Un JWT constă din trei componente principale: antetul, sarcina utilă și semnătura. Antetul conține metadate despre token, inclusiv algoritmul de hashing utilizat pentru a codifica simbolul.
Sarcina utilă conține acreditările reale ale utilizatorului, cum ar fi ID-ul utilizatorului și permisiunile. În sfârșit, semnătura asigură valabilitatea token-ului prin verificarea conținutului acestuia folosind o cheie secretă.
Folosind JWT-uri, puteți autentifica utilizatorii și stoca datele sesiunii, toate în token-ul propriu-zis.
Configurați un proiect Flask și o bază de date MongoDB
Pentru a începe, creați un nou director de proiect folosind un terminal:
mkdir flask-project
cd flask-proiect
Apoi, instalați virtualenv, pentru a crea un mediu local de dezvoltare virtuală pentru proiectul dvs. Flask.
virtualenv venv
În cele din urmă, activați mediul virtual.
# Unix sau MacOS:
sursă venv/bin/activate
# Windows:
.\venv\Scripts\activate
Puteți găsi codul acestui proiect în aceasta Depozitul GitHub.
Instalați pachetele necesare
În directorul rădăcină al folderului de proiect, creați un nou cerințe.txt fișier și adăugați aceste dependențe pentru proiect:
balon
pyjwt
python-dotenv
pymongo
bcrypt
În cele din urmă, rulați comanda de mai jos pentru a instala pachetele. Asigura-te ca ai pip (manager de pachete) instalat; dacă nu, instalați-l pe sistemul dvs. Windows, Mac sau Linux.
pip install -r requirements.txt
Creați o bază de date MongoDB
Continuați și creați o bază de date MongoDB. Puteți configurați o bază de date locală MongoDB, alternativ, creați un cluster pe MongoDB Atlas, un serviciu MongoDB bazat pe cloud.
După ce ați creat baza de date, copiați URI-ul conexiunii, creați un .env fișier în directorul rădăcină al proiectului și adăugați-l după cum urmează:
MONGO_URI=""
În cele din urmă, configurați conexiunea la baza de date din aplicația dvs. Flask. Creaza un nou utils/db.py fișier în directorul rădăcină al proiectului dvs., cu acest cod:
din pymongo import MongoClient
defconnect_to_mongodb(mongo_uri):
client = MongoClient (mongo_uri)
db = client.get_database("utilizatori")
întoarcere db
Această funcție stabilește o conexiune la baza de date MongoDB folosind URI-ul de conexiune furnizat. Apoi creează un nou utilizatorii colecție dacă nu există și returnează instanța corespunzătoare a bazei de date.
Creați serverul Web Flask
Cu baza de date configurată, continuați și creați un app.py fișier în directorul rădăcină al folderului de proiect și adăugați următorul cod pentru a crea o instanță a aplicației Flask.
din balon import Balon
din rute.user_auth import register_routes
din utils.db import connect_to_mongodb
import os
din dotenv import load_dotenvaplicație = Balon (__nume__)
load_dotenv()mongo_uri = os.getenv(„MONGO_URI”)
db = connect_to_mongodb (mongo_uri)register_routes (aplicație, db)
dacă __nume__ == '__principal__':
app.run (depanare=Adevărat)
Creați punctele finale API de autentificare
Pentru a implementa autentificarea utilizatorului în aplicația dvs. Flask, este crucial să definiți punctele finale API necesare care gestionează operațiunile legate de autentificare.
Cu toate acestea, mai întâi, definiți modelul pentru datele utilizatorilor. Pentru a face acest lucru, creați un nou model/user_model.py fișier în directorul rădăcină și adăugați următorul cod.
din pymongo.colecție import Colectie
din bson.objectid import ObjectIdclasăUtilizator:
def__init__(self, colecție: colecție, nume de utilizator: str, parolă: str):
self.collection = colectie
self.username = nume de utilizator
self.parola = parola
defSalvați(de sine):
user_data = {
'nume de utilizator': self.username,
'parola': self.parola
}
rezultat = self.collection.insert_one (date_utilizator)
întoarcere str (result.inserted_id)@staticmethod
deffind_by_id(colecție: colecție, user_id: str):
întoarcere collection.find_one({'_id': ObjectId (user_id)})
@staticmethod
defgăsiți_după_nume de utilizator(colecție: colecție, nume de utilizator: str):
întoarcere collection.find_one({'nume de utilizator': nume de utilizator})
Codul de mai sus specifică a Utilizator clasă care servește ca model de date și definește mai multe metode de interacțiune cu o colecție MongoDB pentru a efectua operațiuni legate de utilizator.
- The Salvați salvează un nou document de utilizator cu numele de utilizator și parola furnizate în colecția MongoDB și returnează ID-ul documentului inserat.
- The find_by_id și găsiți_după_nume de utilizator metodele preiau documentele utilizatorului din colecție pe baza ID-ului de utilizator sau, respectiv, numelui de utilizator furnizat.
Definiți rutele de autentificare
- Să începem prin a defini traseul de înregistrare. Această rută va adăuga date noi despre utilizatori la colecția de utilizatori MongoDB. În directorul rădăcină, creați un nou routes/user_auth.py fișier și următorul cod.
import jwt
din functools import împachetări
din balon import jsonify, cerere, make_response
din modele.model_utilizator import Utilizator
import bcrypt
import osdefregister_routes(aplicație, db):
colecție = db.users
app.config['CHEIE SECRETA'] = os.urandom(24)@app.route('/api/register', methods=['POST'])
defInregistreaza-te():
nume de utilizator = request.json.get('nume de utilizator')
parola = request.json.get('parola')
existent_user = User.find_by_username (colecție, nume de utilizator)
dacă utilizator existent:
întoarcere jsonify({'mesaj': 'Nume de utilizator deja existent!'})
hashed_password = bcrypt.hashpw (parola.encode(„utf-8”), bcrypt.gensalt())
new_user = Utilizator (colecție, nume de utilizator, parola_hashed.decode(„utf-8”))
user_id = new_user.save()întoarcere jsonify({'mesaj': „Utilizatorul s-a înregistrat cu succes!”, 'ID-ul de utilizator': ID-ul de utilizator})
- Implementați funcționalitatea de autentificare, pentru a gestiona procesul de autentificare și a verifica acreditările utilizatorului. Sub traseul de înregistrare, adăugați următorul cod.
Punctul final de conectare face două lucruri: verifică acreditările de utilizator furnizate și, după autentificarea cu succes, generează un JWT unic pentru acel utilizator. Setează acest token ca cookie în răspuns, împreună cu o sarcină utilă JSON care indică o conectare reușită. Dacă acreditările sunt nevalide, va returna un răspuns JSON pentru a indica acest lucru.@app.route('/api/login', methods=['POST'])
deflog in():
nume de utilizator = request.json.get('nume de utilizator')
parola = request.json.get('parola')
user = User.find_by_username (colecție, nume de utilizator)
dacă utilizator:
dacă bcrypt.checkpw (parola.encode(„utf-8”), utilizator['parola'].codifica(„utf-8”)):
token = jwt.encode({'ID-ul de utilizator': str (utilizator['_id'])}, app.config['CHEIE SECRETA'], algoritm=„HS256”)
răspuns = make_response (jsonify({'mesaj': 'Autentificare reușită!'}))
response.set_cookie('jeton', simbol)
întoarcere raspunsîntoarcere jsonify({'mesaj': 'Nume de utilizator sau parola incorecte'})
- Definiți o funcție de decorare care verifică jetoanele web JSON (JWT) transmise împreună cu solicitările API ulterioare. Adăugați codul de mai jos în cadrul register_routes bloc de coduri funcționale.
Această funcție de decorare asigură prezența unui token JWT valid în solicitările API ulterioare. Verifică dacă tokenul lipsește, a expirat sau este valid și returnează un răspuns JSON adecvat dacă este.deftoken_required(f):
@wraps (f)
defdecorat(*args, **kwargs):
token = request.cookies.get('jeton')dacănu jeton:
întoarcere jsonify({'mesaj': „Lipsește tokenul!”}), 401încerca:
date = jwt.decode (token, app.config['CHEIE SECRETA'], algoritmi=[„HS256”])
current_user = User.find_by_id (colecție, date['ID-ul de utilizator'])
cu exceptia jwt. ExpiredSignatureError:
întoarcere jsonify({'mesaj': „Jetonul a expirat!”}), 401
cu exceptia jwt. InvalidTokenError:
întoarcere jsonify({'mesaj': 'Simbol Invalid!'}), 401întoarcere f (utilizator_actual, *args, **kwargs)
întoarcere decorat
- În cele din urmă, creați o rută protejată.
@app.route('/api/users', methods=['GET'])
@token_required
defget_users(utilizator curent):
utilizatori = listă (collection.find({}, {'_id': 0}))
întoarcere jsonify (utilizatori)
Acest punct final se ocupă de logica pentru preluarea datelor utilizatorului din baza de date, dar solicită clientului care trimite cereri să includă un token valid pentru a accesa datele.
În cele din urmă, rulați comanda de mai jos pentru a porni serverul de dezvoltare.
rularea balonului
Pentru a testa înregistrarea, autentificarea și punctul final al utilizatorilor protejați, puteți utiliza Postman sau orice alt client API. Trimite cereri la http://localhost: 5000/api/și observați răspunsurile pentru a verifica funcționalitatea acestor puncte finale API.
Este autentificarea cu jeton o măsură de securitate fără greșeală?
Tokenurile web JSON oferă o modalitate robustă și eficientă de autentificare a utilizatorilor pentru aplicația dvs. web. Cu toate acestea, este important să înțelegeți că autentificarea cu jeton nu este sigură; este doar o piesă dintr-un puzzle de securitate mai mare.
Combinați autentificarea cu simboluri cu alte bune practici de securitate. Nu uitați să monitorizați continuu și să adoptați practici de securitate consecvente; veți îmbunătăți în mod semnificativ securitatea generală a aplicațiilor dvs. Flask.