JSON žiniatinklio prieigos raktus lengva naudoti ir derinti, tačiau jie taip pat suteikia įspūdingą saugumo padidinimą.
Sugadintas autentifikavimas ir toliau yra nuolatinis šiuolaikinių žiniatinklio programų pažeidžiamumas – jis vis dar patenka į 10 didžiausių OWASP API saugumo pavojų.
Šio pažeidžiamumo pasekmės gali būti rimtos. Jie gali suteikti neteisėtą prieigą prie jautrių duomenų ir pažeisti sistemos vientisumą. Norint veiksmingai užtikrinti saugią prieigą prie programų ir jų išteklių, labai svarbu naudoti patikimus autentifikavimo mechanizmus.
Sužinokite, kaip galite įdiegti vartotojo autentifikavimą „Flask“ naudodami JSON žiniatinklio prieigos raktus (JWT), populiarų ir veiksmingą prieigos raktų metodą.
Žetonais pagrįstas autentifikavimas naudojant JSON žiniatinklio prieigos raktus
Žetonu pagrįstas autentifikavimas naudoja šifruotą simbolių eilutę, kad patvirtintų ir įgaliotų prieigą prie sistemos ar išteklių. Šio tipo autentifikavimą galite įdiegti naudodami įvairius metodus, įskaitant seanso prieigos raktus, API raktus ir JSON žiniatinklio prieigos raktus.
Visų pirma JWT siūlo saugų ir kompaktišką būdą perduoti reikalingus vartotojų kredencialus tarp kliento programų ir serverių.
JWT sudaro trys pagrindiniai komponentai: antraštė, naudingoji apkrova ir parašas. Antraštėje yra prieigos rakto metaduomenys, įskaitant maišos algoritmą, naudojamą prieigos raktui koduoti.
Naudingame krovinyje yra tikrieji vartotojo kredencialai, pvz., vartotojo ID ir leidimai. Galiausiai parašas užtikrina žetono galiojimą, patikrindamas jo turinį slaptu raktu.
Naudodami JWT galite autentifikuoti vartotojus ir saugoti seanso duomenis pačiame prieigos rakte.
Sukurkite kolbos projektą ir MongoDB duomenų bazę
Norėdami pradėti, sukurkite naują projekto katalogą naudodami terminalą:
mkdir kolbos projektas
cd kolbos projektas
Toliau įdiekite virtualenv, kad sukurtumėte vietinę virtualią Flask projekto kūrimo aplinką.
virtualenv venv
Galiausiai suaktyvinkite virtualią aplinką.
# Unix arba MacOS:
šaltinis venv/bin/activate
# „Windows“:
.\venv\Scripts\activate
Šio projekto kodą rasite čia GitHub saugykla.
Įdiekite reikiamus paketus
Projekto aplanko šakniniame kataloge sukurkite naują reikalavimai.txt failą ir pridėkite šias projekto priklausomybes:
kolba
pyjwt
python-dotenv
pimongas
bcrypt
Galiausiai paleiskite toliau pateiktą komandą, kad įdiegtumėte paketus. Įsitikinkite, kad turite pip (paketų tvarkyklė) įdiegta; jei ne, įdiekite jį savo Windows, Mac arba Linux sistemoje.
pip install -r reikalavimai.txt
Sukurkite MongoDB duomenų bazę
Eikite į priekį ir sukurkite MongoDB duomenų bazę. Tu gali nustatyti vietinę MongoDB duomenų bazę, alternatyviai, sukurti klasterį MongoDB Atlas, debesies pagrindu veikiančioje MongoDB tarnyboje.
Sukūrę duomenų bazę, nukopijuokite ryšio URI, sukurkite a .env failą savo projekto šakniniame kataloge ir pridėkite jį taip:
MONGO_URI=""
Galiausiai sukonfigūruokite duomenų bazės ryšį naudodami „Flask“ programą. Sukurti naują utils/db.py failą savo projekto šakniniame kataloge su šiuo kodu:
iš pimongas importuoti MongoClient
defconnect_to_mongodb(mongo_uri):
klientas = MongoClient (mongo_uri)
db = client.get_database("vartotojai")
grąžinti db
Ši funkcija užmezga ryšį su MongoDB duomenų baze naudodama pateiktą ryšio URI. Tada sukuriamas naujas vartotojų rinkinį, jei jo nėra, ir grąžina atitinkamą duomenų bazės egzempliorių.
Sukurkite „Flask“ žiniatinklio serverį
Kai duomenų bazė sukonfigūruota, eikite į priekį ir sukurkite app.py failą projekto aplanko šakniniame kataloge ir pridėkite šį kodą, kad sukurtumėte programos „Flask“ egzempliorių.
iš kolba importuoti Kolba
iš routes.user_auth importuoti registras_maršrutai
iš utils.db importuoti connect_to_mongodb
importuoti os
iš dotenv importuoti load_dotenvprograma = Kolba (__name__)
load_dotenv()mongo_uri = os.getenv(„MONGO_URI“)
db = connect_to_mongodb (mongo_uri)register_routes (programa, db)
jeigu __vardas__ == '__pagrindinis__':
app.run (debug=Tiesa)
Sukurkite autentifikavimo API galutinius taškus
Norint įdiegti vartotojo autentifikavimą Flask programoje, labai svarbu apibrėžti būtinus API galutinius taškus, kurie tvarko su autentifikavimu susijusias operacijas.
Tačiau pirmiausia apibrėžkite vartotojų duomenų modelį. Norėdami tai padaryti, sukurkite naują model/user_model.py failą šakniniame kataloge ir pridėkite šį kodą.
iš pymongo.kolekcija importuoti Kolekcija
iš bson.objektinis importuoti Objekto IDklasėVartotojas:
def__init__(savarankiškai, kolekcija: kolekcija, vartotojo vardas: str, slaptažodis: str):
savęs.rinkimas = surinkimas
self.username = vartotojo vardas
self.password = slaptažodis
defsutaupyti(savarankiškai):
vartotojo_duomenys = {
'Vartotojo vardas': self.username,
'Slaptažodis': savarankiškai.slaptažodis
}
rezultatas = self.collection.insert_one (user_data)
grąžinti str (rezultatas.įdėtas_id)@staticmethod
defrasti_pagal_id(rinkinys: kolekcija, vartotojo_id: str):
grąžinti collection.find_one({'_id': ObjectId (user_id)})
@staticmethod
defrasti_pagal_vartotojo vardą(kolekcija: kolekcija, vartotojo vardas: str):
grąžinti collection.find_one({'Vartotojo vardas': Vartotojo vardas})
Aukščiau pateiktas kodas nurodo a Vartotojas klasė, kuri naudojama kaip duomenų modelis ir apibrėžia kelis sąveikos su MongoDB rinkiniu metodus, kad būtų galima atlikti su vartotoju susijusias operacijas.
- The sutaupyti metodas išsaugo naują vartotojo dokumentą su pateiktu vartotojo vardu ir slaptažodžiu MongoDB kolekcijoje ir grąžina įdėto dokumento ID.
- The rasti_pagal_id ir rasti_pagal_vartotojo vardą metodai iš kolekcijos nuskaito vartotojo dokumentus pagal pateiktą vartotojo ID arba vartotojo vardą, atitinkamai.
Apibrėžkite autentifikavimo maršrutus
- Pradėkime nuo registracijos maršruto apibrėžimo. Šis maršrutas įtrauks naujus vartotojo duomenis į MongoDB vartotojų kolekciją. Šakniniame kataloge sukurkite naują routes/user_auth.py failą ir šį kodą.
importuoti jwt
iš funkcinės priemonės importuoti įvyniojimai
iš kolba importuoti jsonify, request, make_response
iš modeliai.vartotojo_modelis importuoti Vartotojas
importuoti bcrypt
importuoti osdefregistras_maršrutai(programa, db):
kolekcija = db.vartotojai
app.config[„SECRET_KEY“] = os.urandom(24)@app.route('/api/register', method=['POST'])
defRegistruotis():
vartotojo vardas = request.json.get('Vartotojo vardas')
slaptažodis = request.json.get('Slaptažodis')
meglévő_vartotojas = User.find_by_username (rinkinys, vartotojo vardas)
jeigu esamas_vartotojas:
grąžinti jsonify({"žinutė": 'Vardas jau egzistuoja!'})
hashed_password = bcrypt.hashpw (password.encode("utf-8"), bcrypt.gensalt())
new_user = Vartotojas (rinkinys, vartotojo vardas, hashed_password.decode("utf-8"))
vartotojo_id = naujas_vartotojas.save()grąžinti jsonify({"žinutė": 'Vartotojas sėkmingai užsiregistravo!', 'Vartotojo ID': Vartotojo ID})
- Įdiekite prisijungimo funkciją, kad galėtumėte atlikti autentifikavimo procesą ir patikrinti vartotojo kredencialus. Prie registracijos maršruto pridėkite šį kodą.
Prisijungimo galutinis taškas atlieka du dalykus: patikrina pateiktus vartotojo kredencialus ir, sėkmingai patvirtinus, sukuria unikalų to vartotojo JWT. Jis nustato šį prieigos raktą kaip slapuką atsakyme kartu su JSON naudinguoju kroviniu, rodančiu sėkmingą prisijungimą. Jei kredencialai neteisingi, jis grąžins JSON atsakymą, kad tai nurodytų.@app.route('/api/login', method=['POST'])
defPrisijungti():
vartotojo vardas = request.json.get('Vartotojo vardas')
slaptažodis = request.json.get('Slaptažodis')
user = User.find_by_username (rinkinys, vartotojo vardas)
jeigu Vartotojas:
jeigu bcrypt.checkpw (password.encode("utf-8"), Vartotojas['Slaptažodis'].encode("utf-8")):
token = jwt.encode({'Vartotojo ID': str (vartotojas['_id'])}, app.config[„SECRET_KEY“], algoritmas=„HS256“)
atsakymas = make_response (jsonify({"žinutė": 'Prisijungimas sėkmingas!'}))
response.set_cookie("žetonas", ženklas)
grąžinti atsakymągrąžinti jsonify({"žinutė": 'Neteisingas prisijungimo vardas arba slaptažodis'})
- Apibrėžkite dekoratoriaus funkciją, kuri patvirtina JSON žiniatinklio prieigos raktus (JWT), perduodamus kartu su vėlesnėmis API užklausomis. Pridėkite žemiau esantį kodą registras_maršrutai funkcinio kodo blokas.
Ši dekoratoriaus funkcija užtikrina, kad vėlesnėse API užklausose būtų galiojantis JWT prieigos raktas. Ji patikrina, ar prieigos rakto nėra, ar nepasibaigė jo galiojimo laikas arba jis galioja, ir grąžina atitinkamą JSON atsakymą, jei toks yra.deftoken_requiredf):
@wraps (f)
defpapuoštas(*args, **kwargs):
token = request.cookies.get("žetonas")jeigune tokenas:
grąžinti jsonify({"žinutė": 'Trūksta žetono!'}), 401bandyti:
duomenys = jwt.decode (token, app.config[„SECRET_KEY“], algoritmai=[„HS256“])
current_user = User.find_by_id (rinkinys, duomenys['Vartotojo ID'])
išskyrus jwt. Pasibaigusio parašo klaida:
grąžinti jsonify({"žinutė": „Žetonas baigėsi!“}), 401
išskyrus jwt. InvalidTokenError:
grąžinti jsonify({"žinutė": "Neteisingas prieigos raktas!"}), 401grąžinti f (dabartinis_vartotojas, *args, **kwargs)
grąžinti papuoštas
- Galiausiai sukurkite apsaugotą maršrutą.
@app.route('/api/users', method=['GET'])
@token_required
defget_users(Dabartinis vartotojas):
vartotojai = sąrašas (collection.find({}, {'_id': 0}))
grąžinti jsonify (vartotojai)
Šis galutinis taškas tvarko vartotojo duomenų gavimo iš duomenų bazės logiką, tačiau reikalauja, kad klientas, siunčiantis užklausas, įtrauktų galiojantį prieigos raktą.
Galiausiai paleiskite toliau pateiktą komandą, kad suaktyvintumėte kūrimo serverį.
kolbos paleidimas
Norėdami patikrinti registraciją, prisijungimą ir apsaugotą vartotojų galinį tašką, galite naudoti Postman arba bet kurį kitą API klientą. Siųsti prašymus į http://localhost: 5000/api/ir stebėkite atsakymus, kad patikrintumėte šių API galinių taškų funkcionalumą.
Ar žetonų autentifikavimas yra patikima saugumo priemonė?
JSON žiniatinklio prieigos raktai yra patikimas ir efektyvus būdas autentifikuoti jūsų žiniatinklio programos naudotojus. Tačiau svarbu suprasti, kad žetonų autentifikavimas nėra patikimas; tai tik viena didesnės saugumo galvosūkio dalis.
Derinkite prieigos rakto autentifikavimą su kitomis geriausiomis saugos praktikomis. Nepamirškite nuolat stebėti ir taikyti nuoseklią saugos praktiką; žymiai padidinsite bendrą Flask programų saugumą.