JSON web tokeni jednostavni su za korištenje i otklanjanje pogrešaka, ali također nude impresivno povećanje sigurnosti.
Neispravna provjera autentičnosti i dalje je stalna ranjivost u modernim web aplikacijama—i dalje je visoko rangirana među OWASP-ovih 10 najvećih sigurnosnih rizika za API.
Učinci ove ranjivosti mogu biti ozbiljni. Oni mogu odobriti neovlašteni pristup osjetljivim podacima i ugroziti integritet sustava. Kako biste učinkovito osigurali siguran pristup aplikacijama i njihovim resursima, ključno je da koristite robusne mehanizme provjere autentičnosti.
Saznajte kako možete implementirati autentifikaciju korisnika u Flasku pomoću JSON web tokena (JWT), popularne i učinkovite metode temeljene na tokenu.
Autentifikacija temeljena na tokenu pomoću JSON web tokena
Autentifikacija temeljena na tokenu koristi šifrirani niz znakova za provjeru valjanosti i autorizaciju pristupa sustavu ili resursu. Ovu vrstu autentifikacije možete implementirati pomoću različitih metoda, uključujući tokene sesije, API ključeve i JSON web tokene.
JWT-ovi posebno nude siguran i kompaktan pristup za prijenos potrebnih korisničkih vjerodajnica između aplikacija na strani klijenta i poslužitelja.
JWT se sastoji od tri glavne komponente: zaglavlje, korisni teret i potpis. Zaglavlje sadrži metapodatke o tokenu, uključujući algoritam raspršivanja koji se koristi za kodiranje tokena.
Korisni teret sadrži stvarne korisničke vjerodajnice, kao što su korisnički ID i dopuštenja. Na kraju, potpis osigurava valjanost tokena provjerom njegovog sadržaja pomoću tajnog ključa.
Koristeći JWT, možete autentificirati korisnike i pohraniti podatke o sesiji unutar samog tokena.
Postavite Flask projekt i MongoDB bazu podataka
Za početak kreirajte novi direktorij projekta pomoću terminala:
mkdir flask-projekt
cd flask-projekt
Zatim instalirajte virtualenv, za stvaranje lokalnog virtualnog razvojnog okruženja za vaš Flask projekt.
virtualenv venv
Na kraju, aktivirajte virtualno okruženje.
# Unix ili MacOS:
izvor venv/bin/aktivirati
# Windows:
.\venv\Skripte\aktivirati
Kôd ovog projekta možete pronaći ovdje GitHub spremište.
Instalirajte potrebne pakete
U korijenskom direktoriju mape projekta stvorite novu zahtjevi.txt datoteku i dodajte ove ovisnosti za projekt:
pljoska
pyjwt
python-dotenv
pimongo
bcrypt
Na kraju, pokrenite naredbu u nastavku da biste instalirali pakete. Provjerite jeste li pip (upravitelj paketa) instaliran; ako ne, instalirajte ga na svoj Windows, Mac ili Linux sustav.
pip install -r zahtjevi.txt
Stvorite MongoDB bazu podataka
Samo naprijed i stvorite MongoDB bazu podataka. Možeš postaviti lokalnu MongoDB bazu podataka, alternativno, stvoriti klaster na MongoDB Atlasu, MongoDB usluzi temeljenoj na oblaku.
Nakon što stvorite bazu podataka, kopirajte URI veze, stvorite a .env datoteku u korijenskom direktoriju vašeg projekta i dodajte je na sljedeći način:
MONGO_URI=""
Na kraju, konfigurirajte vezu s bazom podataka iz vaše Flask aplikacije. Stvorite novi utils/db.py datoteku u korijenskom direktoriju vašeg projekta, s ovim kodom:
iz pimongo uvoz MongoClient
defpovezivanje_na_mongodb(mongo_uri):
klijent = MongoClient (mongo_uri)
db = client.get_database("korisnici")
povratak db
Ova funkcija uspostavlja vezu s MongoDB bazom podataka koristeći navedeni URI veze. Zatim stvara novi korisnika zbirka ako ne postoji i vraća odgovarajuću instancu baze podataka.
Napravite Flask web poslužitelj
S konfiguriranom bazom podataka, samo naprijed i stvorite app.py datoteku u korijenskom direktoriju mape projekta i dodajte sljedeći kod za stvaranje instance Flask aplikacije.
iz pljoska uvoz Boca
iz rute.user_auth uvoz registar_rute
iz utils.db uvoz povezivanje_na_mongodb
uvoz os
iz dotenv uvoz load_dotenvaplikacija = Flask (__ime__)
load_dotenv()mongo_uri = os.getenv('MONGO_URI')
db = povezivanje_na_mongodb (mongo_uri)register_routes (aplikacija, db)
ako __ime__ == '__glavni__':
app.run (debug=Pravi)
Stvorite krajnje točke API-ja za provjeru autentičnosti
Za implementaciju provjere autentičnosti korisnika u vašoj aplikaciji Flask, ključno je definirati potrebne krajnje točke API-ja koje upravljaju operacijama povezanim s autentifikacijom.
Međutim, prvo definirajte model za korisničke podatke. Da biste to učinili, stvorite novi model/korisnički_model.py datoteku u korijenskom direktoriju i dodajte sljedeći kod.
iz pymongo.zbirka uvoz Kolekcija
iz bson.objectid uvoz ObjectIdrazredaKorisnik:
def__u tome__(sebe, zbirka: zbirka, korisničko ime: str, lozinka: str):
samo.zbirka = zbirka
self.username = korisničko ime
self.password = lozinka
defuštedjeti(sebe):
korisnički_podaci = {
'Korisničko ime': samo.korisničko ime,
'lozinka': samozaporka
}
rezultat = self.collection.insert_one (user_data)
povratak str (result.inserted_id)@statička metoda
defpronađi_po_id-u(kolekcija: zbirka, korisnički_id: str):
povratak zbirka.find_one({'_iskaznica': ObjectId (user_id)})
@statička metoda
defpronađi_po_korisničkom imenu(kolekcija: Kolekcija, korisničko ime: str):
povratak zbirka.find_one({'Korisničko ime': Korisničko ime})
Gornji kod navodi a Korisnik klasa koja služi kao podatkovni model i definira nekoliko metoda za interakciju s MongoDB kolekcijom za izvođenje operacija povezanih s korisnikom.
- The uštedjeti metoda sprema novi korisnički dokument s navedenim korisničkim imenom i lozinkom u kolekciju MongoDB i vraća ID umetnutog dokumenta.
- The pronađi_po_id-u i pronađi_po_korisničkom imenu metode dohvaćaju korisničke dokumente iz zbirke na temelju navedenog korisničkog ID-a ili korisničkog imena.
Definirajte rute provjere autentičnosti
- Počnimo s definiranjem rute registracije. Ova ruta će dodati nove korisničke podatke u MongoDB korisničku zbirku. U korijenskom direktoriju stvorite novi routes/user_auth.py datoteku i sljedeći kod.
uvoz jwt
iz functools uvoz oblozi
iz pljoska uvoz jsonify, zahtjev, make_response
iz modeli.korisnički_model uvoz Korisnik
uvoz bcrypt
uvoz osdefregistar_rute(aplikacija, db):
zbirka = db.users
app.config['SECRET_KEY'] = os.urandom(24)@app.route('/api/register', metode=['POST'])
defRegistar():
korisničko ime = request.json.get('Korisničko ime')
lozinka = request.json.get('lozinka')
postojeći_korisnik = User.find_by_username (kolekcija, korisničko ime)
ako postojeći_korisnik:
povratak jsonify({'poruka': 'Korisničko ime već postoji!'})
hashed_password = bcrypt.hashpw (password.encode('utf-8'), bcrypt.gensalt())
new_user = Korisnik (kolekcija, korisničko ime, hasshed_password.decode('utf-8'))
user_id = new_user.save()povratak jsonify({'poruka': 'Korisnik se uspješno registrirao!', 'user_id': user_id})
- Implementirajte funkciju prijave za upravljanje postupkom provjere autentičnosti i provjeru korisničkih vjerodajnica. Ispod rute registracije dodajte sljedeći kod.
Krajnja točka za prijavu čini dvije stvari: provjerava dostavljene korisničke vjerodajnice i, nakon uspješne provjere autentičnosti, generira jedinstveni JWT za tog korisnika. Postavlja ovaj token kao kolačić u odgovoru, zajedno s JSON sadržajem koji označava uspješnu prijavu. Ako su vjerodajnice nevažeće, vratit će JSON odgovor koji to označava.@app.route('/api/login', methods=['POST'])
defprijaviti se():
korisničko ime = request.json.get('Korisničko ime')
lozinka = request.json.get('lozinka')
korisnik = User.find_by_username (kolekcija, korisničko ime)
ako korisnik:
ako bcrypt.checkpw (password.encode('utf-8'), korisnik['lozinka'].encode('utf-8')):
token = jwt.encode({'user_id': str (korisnik['_iskaznica'])}, app.config['SECRET_KEY'], algoritam='HS256')
odgovor = make_response (jsonify({'poruka': 'Uspješna prijava!'}))
response.set_cookie('znak', token)
povratak odgovorpovratak jsonify({'poruka': 'Neispravno korisničko ime ili lozinka'})
- Definirajte funkciju dekoratora koja provjerava JSON web tokene (JWT) proslijeđene zajedno s kasnijim API zahtjevima. Dodajte donji kod unutar registar_rute blok funkcijskog koda.
Ova funkcija dekoratera osigurava prisutnost valjanog JWT tokena u narednim API zahtjevima. Provjerava nedostaje li token, istekao je ili je valjan i vraća odgovarajući JSON odgovor ako jest.deftoken_required(f):
@omoti (f)
defukrašena(*args, **kwargs):
token = request.cookies.get('znak')akone znak:
povratak jsonify({'poruka': 'Token nedostaje!'}), 401probati:
podaci = jwt.decode (token, app.config['SECRET_KEY'], algoritmi=['HS256'])
current_user = User.find_by_id (zbirka, podaci['user_id'])
osim jwt. ExpiredSignatureError:
povratak jsonify({'poruka': 'Token je istekao!'}), 401
osim jwt. InvalidTokenError:
povratak jsonify({'poruka': 'Pogrešan token!'}), 401povratak f (trenutni_korisnik, *args, **kwargs)
povratak ukrašena
- Na kraju, stvorite zaštićenu rutu.
@app.route('/api/users', metode=['GET'])
@token_required
defdobiti_korisnike(trenutni korisnik):
korisnici = popis (collection.find({}, {'_iskaznica': 0}))
povratak jsonify (korisnici)
Ova krajnja točka upravlja logikom za dohvaćanje korisničkih podataka iz baze podataka, ali zahtijeva da klijent koji šalje zahtjeve uključi važeći token za pristup podacima.
Na kraju, pokrenite donju naredbu da pokrenete razvojni poslužitelj.
flask run
Za testiranje registracije, prijave i krajnje točke zaštićenih korisnika možete koristiti Postman ili bilo koji drugi API klijent. Pošalji zahtjeve na http://localhost: 5000/api/i promatrajte odgovore kako biste provjerili funkcionalnost ovih API krajnjih točaka.
Je li autentifikacija tokena besprijekorna sigurnosna mjera?
JSON web tokeni pružaju robustan i učinkovit način autentifikacije korisnika za vašu web aplikaciju. Međutim, važno je razumjeti da autentifikacija tokenom nije sigurna; to je samo jedan dio veće sigurnosne slagalice.
Kombinirajte autentifikaciju tokena s drugim najboljim sigurnosnim praksama. Ne zaboravite kontinuirano nadzirati i usvojiti dosljedne sigurnosne prakse; značajno ćete poboljšati ukupnu sigurnost svojih Flask aplikacija.