JSON Web Tokens er nemme at bruge og fejlfinde, men de tilbyder også et imponerende sikkerhedsboost.

Ødelagt autentificering er fortsat en vedvarende sårbarhed i moderne webapplikationer – den rangerer stadig højt blandt OWASPs top 10 API-sikkerhedsrisici.

Virkningerne af denne sårbarhed kan være alvorlige. De kan give uautoriseret adgang til følsomme data og kompromittere systemets integritet. For effektivt at sikre sikker adgang til applikationer og deres ressourcer er det afgørende, at du bruger robuste godkendelsesmekanismer.

Find ud af, hvordan du kan implementere brugergodkendelse i Flask ved hjælp af JSON Web Tokens (JWT), en populær og effektiv token-baseret metode.

Token-baseret godkendelse ved hjælp af JSON-webtokens

Token-baseret godkendelse bruger en krypteret streng af tegn til at validere og autorisere adgang til et system eller en ressource. Du kan implementere denne type godkendelse ved hjælp af forskellige metoder, herunder sessionstokens, API-nøgler og JSON Web Tokens.

Især JWT'er tilbyder en sikker og kompakt tilgang til overførsel af de nødvendige brugeres legitimationsoplysninger mellem klientsideapplikationer og servere.

instagram viewer

En JWT består af tre hovedkomponenter: overskriften, nyttelasten og signaturen. Headeren indeholder metadata om tokenet, inklusive hashing-algoritmen, der bruges til at kode tokenet.

Nyttelasten indeholder de faktiske brugerlegitimationsoplysninger, såsom bruger-id og tilladelser. Til sidst sikrer signaturen gyldigheden af ​​tokenet ved at verificere dets indhold ved hjælp af en hemmelig nøgle.

Ved at bruge JWT'er kan du godkende brugere og gemme sessionsdata alt sammen inden for selve tokenet.

Opsæt et Flask-projekt og en MongoDB-database

For at komme i gang skal du oprette en ny projektmappe ved hjælp af en terminal:

mkdir kolbe-projekt
cd kolbe-projekt

Installer derefter virtualenv, for at skabe et lokalt virtuelt udviklingsmiljø til dit Flask-projekt.

virtualenv venv

Til sidst skal du aktivere det virtuelle miljø.

# Unix eller MacOS: 
kilde venv/bin/activate

# Windows:
.\venv\Scripts\aktiver

Du kan finde dette projekts kode i denne GitHub-depot.

Installer de nødvendige pakker

I rodmappen i din projektmappe skal du oprette en ny krav.txt fil, og tilføj disse afhængigheder for projektet:

kolbe
pyjwt
python-dotenv
pymongo
bcrypt

Til sidst skal du køre kommandoen nedenfor for at installere pakkerne. Sørg for, at du har pip (pakkehåndtering) installeret; hvis ikke, installer det på dit Windows-, Mac- eller Linux-system.

pip install -r requirements.txt

Opret en MongoDB-database

Gå videre og opret en MongoDB-database. Du kan oprette en lokal MongoDB-database, alternativt, oprette en klynge på MongoDB Atlas, en cloud-baseret MongoDB-tjeneste.

Når du har oprettet databasen, skal du kopiere forbindelses-URI'en, oprette en .env fil i dit projekts rodmappen, og tilføj den som følger:

MONGO_URI=""

Til sidst skal du konfigurere databaseforbindelsen fra din Flask-applikation. Opret en ny utils/db.py fil i dit projekts rodbibliotek med denne kode:

fra pymongo importere MongoClient

defconnect_to_mongodb(mongo_uri):
klient = MongoClient (mongo_uri)
db = klient.get_database("brugere")
Vend tilbage db

Denne funktion etablerer en forbindelse til MongoDB-databasen ved hjælp af den medfølgende forbindelses-URI. Det skaber så en ny brugere samling, hvis den ikke findes, og returnerer den tilsvarende databaseforekomst.

Opret Flask Web Server

Med databasen konfigureret, gå videre og opret en app.py fil i rodmappen i projektmappen, og tilføj følgende kode for at oprette en forekomst af Flask-applikationen.

fra kolbe importere Kolbe
fra routes.user_auth importere register_ruter
fra utils.db importere connect_to_mongodb
importere os
fra dotenv importere load_dotenv

app = Kolbe (__navn__)
load_dotenv()

mongo_uri = os.getenv('MONGO_URI')
db = connect_to_mongodb (mongo_uri)

register_ruter (app, db)

hvis __navn__ == '__main__':
app.run (debug=Rigtigt)

Opret Authentication API Endpoints

For at implementere brugergodkendelse i din Flask-applikation er det afgørende at definere de nødvendige API-endepunkter, der håndterer godkendelsesrelaterede operationer.

Men først skal du definere modellen for brugernes data. For at gøre det skal du oprette en ny model/bruger_model.py fil i rodmappen, og tilføj følgende kode.

fra pymongo.samling importere Kollektion
fra bson.objektid importere ObjectId

klasseBruger:
def__i det__(selv, samling: Samling, brugernavn: str, adgangskode: str):
self.collection = samling
self.username = brugernavn
self.password = adgangskode
defGemme(selv):
bruger_data = {
'brugernavn': selv.brugernavn,
'adgangskode': selv.adgangskode
}
resultat = self.collection.insert_one (brugerdata)
Vend tilbage str (result.inserted_id)

@statisk metode
deffind_by_id(samling: Samling, bruger_id: str):
Vend tilbage collection.find_one({'_id': ObjectId (user_id)})

@statisk metode
deffind_by_brugernavn(samling: Samling, brugernavn: str):
Vend tilbage collection.find_one({'brugernavn': brugernavn})

Koden ovenfor angiver en Bruger klasse, der fungerer som en datamodel og definerer flere metoder til at interagere med en MongoDB-samling for at udføre brugerrelaterede operationer.

  1. Det Gemme metoden gemmer et nyt brugerdokument med det angivne brugernavn og adgangskode til MongoDB-samlingen og returnerer ID'et for det indsatte dokument.
  2. Det find_by_id og find_by_brugernavn metoder henter brugerdokumenter fra samlingen baseret på henholdsvis det angivne bruger-id eller brugernavn.

Definer godkendelsesruterne

  1. Lad os starte med at definere registreringsruten. Denne rute tilføjer nye brugerdata til MongoDB-brugersamlingen. I rodmappen skal du oprette en ny routes/user_auth.py fil og følgende kode.
    importere jwt
    fra funktionsværktøjer importere wraps
    fra kolbe importere jsonify, request, make_response
    fra models.user_model importere Bruger
    importere bcrypt
    importere os

    defregister_ruter(app, db):
    samling = db.brugere
    app.config['SECRET_KEY'] = os.urandom(24)

    @app.route('/api/register', methods=['POST'])
    defTilmeld():

    brugernavn = request.json.get('brugernavn')
    password = request.json.get('adgangskode')

    existerende_bruger = Bruger.find_efter_brugernavn (samling, brugernavn)
    hvis eksisterende_bruger:
    Vend tilbage jsonify({'besked': 'Brugernavnet eksisterer allerede!'})

    hashed_password = bcrypt.hashpw (password.encode('utf-8'), bcrypt.gensalt())
    new_user = Bruger (samling, brugernavn, hashed_password.decode('utf-8'))
    user_id = new_user.save()

    Vend tilbage jsonify({'besked': 'Bruger registreret med succes!', 'bruger ID': bruger ID})

  2. Implementer login-funktionaliteten for at håndtere godkendelsesprocessen og verificere brugeroplysninger. Tilføj følgende kode under registreringsruten.
     @app.route('/api/login', methods=['POST'])
    defLog på():
    brugernavn = request.json.get('brugernavn')
    password = request.json.get('adgangskode')
    bruger = Bruger.find_efter_brugernavn (samling, brugernavn)
    hvis bruger:
    hvis bcrypt.checkpw (password.encode('utf-8'), bruger['adgangskode'].encode('utf-8')):
    token = jwt.encode({'bruger ID': str (bruger['_id'])}, app.config['SECRET_KEY'], algoritme='HS256')

    respons = make_response (jsonify({'besked': 'Login lykkedes!'}))
    response.set_cookie('polet', polet)
    Vend tilbage respons

    Vend tilbage jsonify({'besked': 'Ugyldigt brugernavn eller kodeord'})

    Login-slutpunktet gør to ting: det verificerer de leverede brugerlegitimationsoplysninger, og efter vellykket godkendelse genererer det en unik JWT for denne bruger. Det sætter dette token som en cookie i svaret sammen med en JSON-nyttelast, der indikerer et vellykket login. Hvis legitimationsoplysningerne er ugyldige, returnerer den et JSON-svar for at angive det.
  3. Definer en dekorationsfunktion, der verificerer JSON Web Tokens (JWT'er), der sendes sammen med efterfølgende API-anmodninger. Tilføj koden nedenfor inden for register_ruter funktionskodeblok.
    deftoken_required(f):
    @omslag (f)
    defpyntet op(*args, **kwargs):
    token = request.cookies.get('polet')

    hvisikke polet:
    Vend tilbage jsonify({'besked': 'Token mangler!'}), 401

    prøve:
    data = jwt.decode (token, app.config['SECRET_KEY'], algoritmer=['HS256'])
    current_user = User.find_by_id (indsamling, data['bruger ID'])
    undtagen jwt. ExpiredSignatureError:
    Vend tilbage jsonify({'besked': 'Token er udløbet!'}), 401
    undtagen jwt. InvalidTokenError:
    Vend tilbage jsonify({'besked': 'Ugyldig Token!'}), 401

    Vend tilbage f (current_user, *args, **kwargs)

    Vend tilbage pyntet op

    Denne dekorationsfunktion sikrer tilstedeværelsen af ​​et gyldigt JWT-token i efterfølgende API-anmodninger. Det tjekker, om tokenet mangler, er udløbet eller gyldigt, og returnerer et passende JSON-svar, hvis det er det.
  4. Til sidst skal du oprette en beskyttet rute.
     @app.route('/api/brugere', methods=['GET'])
    @token_required
    deffå_brugere(nuværende bruger):
    brugere = liste (collection.find({}, {'_id': 0}))
    Vend tilbage jsonify (brugere)

Dette slutpunkt håndterer logikken til at hente brugerdata fra databasen, men det kræver, at klienten, der sender anmodninger, inkluderer et gyldigt token for at få adgang til dataene.

Kør endelig kommandoen nedenfor for at skrue udviklingsserveren op.

kolbe løb

For at teste registreringen, login og de beskyttede brugeres slutpunkt kan du bruge Postman eller enhver anden API-klient. Send anmodninger til http://localhost: 5000/api/og observer svarene for at verificere funktionaliteten af ​​disse API-endepunkter.

Er token-godkendelse en idiotsikker sikkerhedsforanstaltning?

JSON Web Tokens giver en robust og effektiv måde at autentificere brugere til din webapp på. Det er dog vigtigt at forstå, at token-godkendelse ikke er idiotsikker; det er kun én brik i et større sikkerhedspuslespil.

Kombiner token-godkendelse med andre bedste praksisser for sikkerhed. Husk at overvåge kontinuerligt og vedtage konsekvent sikkerhedspraksis; du vil forbedre den overordnede sikkerhed af dine Flask-applikationer markant.