Τα JSON Web Tokens είναι εύκολα στη χρήση και τον εντοπισμό σφαλμάτων, αλλά προσφέρουν επίσης μια εντυπωσιακή ενίσχυση ασφάλειας.
Ο κατεστραμμένος έλεγχος ταυτότητας εξακολουθεί να είναι μια επίμονη ευπάθεια στις σύγχρονες εφαρμογές Ιστού — εξακολουθεί να βρίσκεται σε υψηλή θέση στους 10 κορυφαίους κινδύνους ασφαλείας API του OWASP.
Οι επιπτώσεις αυτής της ευπάθειας μπορεί να είναι σοβαρές. Μπορούν να παραχωρήσουν μη εξουσιοδοτημένη πρόσβαση σε ευαίσθητα δεδομένα και να θέσουν σε κίνδυνο την ακεραιότητα του συστήματος. Για να διασφαλίσετε αποτελεσματικά την ασφαλή πρόσβαση στις εφαρμογές και τους πόρους τους, είναι ζωτικής σημασίας να χρησιμοποιείτε ισχυρούς μηχανισμούς ελέγχου ταυτότητας.
Μάθετε πώς μπορείτε να εφαρμόσετε τον έλεγχο ταυτότητας χρήστη στο Flask χρησιμοποιώντας τα JSON Web Tokens (JWT), μια δημοφιλή και αποτελεσματική μέθοδο που βασίζεται σε διακριτικά.
Έλεγχος ταυτότητας που βασίζεται σε διακριτικά με χρήση διακριτικών διαδικτύου JSON
Ο έλεγχος ταυτότητας που βασίζεται σε διακριτικά χρησιμοποιεί μια κρυπτογραφημένη σειρά χαρακτήρων για να επικυρώσει και να εξουσιοδοτήσει την πρόσβαση σε ένα σύστημα ή έναν πόρο. Μπορείτε να εφαρμόσετε αυτόν τον τύπο ελέγχου ταυτότητας χρησιμοποιώντας διάφορες μεθόδους, συμπεριλαμβανομένων των διακριτικών συνεδρίας, των κλειδιών API και των Διακριτικών Ιστού JSON.
Τα JWT, ειδικότερα, προσφέρουν μια ασφαλή και συμπαγή προσέγγιση για τη μετάδοση των απαιτούμενων διαπιστευτηρίων των χρηστών μεταξύ εφαρμογών πελάτη και διακομιστών.
Ένα JWT αποτελείται από τρία κύρια στοιχεία: την επικεφαλίδα, το ωφέλιμο φορτίο και την υπογραφή. Η κεφαλίδα περιέχει μεταδεδομένα σχετικά με το διακριτικό, συμπεριλαμβανομένου του αλγόριθμου κατακερματισμού που χρησιμοποιείται για την κωδικοποίηση του διακριτικού.
Το ωφέλιμο φορτίο περιέχει τα πραγματικά διαπιστευτήρια χρήστη, όπως το αναγνωριστικό χρήστη και τα δικαιώματα. Τέλος, η υπογραφή διασφαλίζει την εγκυρότητα του διακριτικού επαληθεύοντας το περιεχόμενό του χρησιμοποιώντας ένα μυστικό κλειδί.
Χρησιμοποιώντας JWT, μπορείτε να ελέγξετε την ταυτότητα των χρηστών και να αποθηκεύσετε δεδομένα περιόδου σύνδεσης όλα μέσα στο ίδιο το διακριτικό.
Ρυθμίστε ένα έργο Flask και μια βάση δεδομένων MongoDB
Για να ξεκινήσετε, δημιουργήστε έναν νέο κατάλογο έργου χρησιμοποιώντας ένα τερματικό:
mkdir flask-project
cd flask-project
Στη συνέχεια, εγκαταστήστε virtualenv, για να δημιουργήσετε ένα τοπικό εικονικό περιβάλλον ανάπτυξης για το έργο σας Flask.
virtualenv venv
Τέλος, ενεργοποιήστε το εικονικό περιβάλλον.
# Unix ή MacOS:
πηγή venv/bin/activate
# Windows:
.\venv\Scripts\ενεργοποίηση
Μπορείτε να βρείτε τον κωδικό αυτού του έργου σε αυτό Αποθετήριο GitHub.
Εγκαταστήστε τα απαιτούμενα πακέτα
Στον ριζικό κατάλογο του φακέλου του έργου σας, δημιουργήστε ένα νέο απαιτήσεις.txt αρχείο και προσθέστε αυτές τις εξαρτήσεις για το έργο:
φλάσκα
pyjwt
python-dotenv
pymongo
bcrypt
Τέλος, εκτελέστε την παρακάτω εντολή για να εγκαταστήσετε τα πακέτα. Βεβαιωθείτε ότι έχετε κουκούτσι (διαχειριστής πακέτων) εγκατεστημένο. αν όχι, εγκαταστήστε το στο σύστημα Windows, Mac ή Linux.
pip install -r απαιτήσεις.txt
Δημιουργήστε μια βάση δεδομένων MongoDB
Προχωρήστε και δημιουργήστε μια βάση δεδομένων MongoDB. Μπορείς δημιουργήστε μια τοπική βάση δεδομένων MongoDB, εναλλακτικά, δημιουργήστε ένα σύμπλεγμα στο MongoDB Atlas, μια υπηρεσία MongoDB που βασίζεται σε σύννεφο.
Αφού δημιουργήσετε τη βάση δεδομένων, αντιγράψτε το URI σύνδεσης, δημιουργήστε ένα .env αρχείο στον ριζικό κατάλογο του έργου σας και προσθέστε τον ως εξής:
MONGO_URI=""
Τέλος, διαμορφώστε τη σύνδεση της βάσης δεδομένων από την εφαρμογή Flask. Δημιούργησε ένα νέο utils/db.py αρχείο στον ριζικό κατάλογο του έργου σας, με αυτόν τον κωδικό:
από pymongo εισαγωγή MongoClient
defconnect_to_mongodb(mongo_uri):
πελάτης = MongoClient (mongo_uri)
db = client.get_database("χρήστες")
ΕΠΙΣΤΡΟΦΗ db
Αυτή η συνάρτηση δημιουργεί μια σύνδεση με τη βάση δεδομένων MongoDB χρησιμοποιώντας το παρεχόμενο URI σύνδεσης. Στη συνέχεια δημιουργεί ένα νέο χρήστες συλλογή εάν δεν υπάρχει και επιστρέφει την αντίστοιχη παρουσία βάσης δεδομένων.
Δημιουργήστε τον διακομιστή Web Flask
Με τη βάση δεδομένων διαμορφωμένη, προχωρήστε και δημιουργήστε ένα app.py αρχείο στον ριζικό κατάλογο του φακέλου του έργου και προσθέστε τον ακόλουθο κώδικα για να δημιουργήσετε μια παρουσία της εφαρμογής Flask.
από φλάσκα εισαγωγή Φλάσκα
από διαδρομές.user_auth εισαγωγή register_routes
από utils.db εισαγωγή connect_to_mongodb
εισαγωγή os
από dotenv εισαγωγή load_dotenvapp = Flask (__name__)
load_dotenv()mongo_uri = os.getenv('MONGO_URI')
db = connect_to_mongodb (mongo_uri)register_routes (εφαρμογή, db)
αν __όνομα__ == '__κύριος__':
app.run (debug=Αληθής)
Δημιουργήστε τα τελικά σημεία του API ελέγχου ταυτότητας
Για να εφαρμόσετε τον έλεγχο ταυτότητας χρήστη στην εφαρμογή σας Flask, είναι σημαντικό να ορίσετε τα απαραίτητα τελικά σημεία API που χειρίζονται λειτουργίες που σχετίζονται με τον έλεγχο ταυτότητας.
Ωστόσο, πρώτα, ορίστε το μοντέλο για τα δεδομένα των χρηστών. Για να το κάνετε αυτό, δημιουργήστε ένα νέο model/user_model.py αρχείο στον ριζικό κατάλογο και προσθέστε τον ακόλουθο κώδικα.
από pymongo.συλλογή εισαγωγή Συλλογή
από bson.objectid εισαγωγή ObjectIdτάξηΧρήστης:
def__μέσα σε αυτό__(εαυτός, συλλογή: Συλλογή, όνομα χρήστη: str, κωδικός πρόσβασης: str):
αυτο.συλλογή = συλλογή
self.username = όνομα χρήστη
self.password = κωδικός πρόσβασης
defαποθηκεύσετε(εαυτός):
user_data = {
'όνομα χρήστη': self.username,
'Κωδικός πρόσβασης': αυτο.κωδικός
}
result = self.collection.insert_one (user_data)
ΕΠΙΣΤΡΟΦΗ str (result.inserted_id)@staticmethod
deffind_by_id(συλλογή: Συλλογή, user_id: str):
ΕΠΙΣΤΡΟΦΗ collection.find_one({'_ταυτότητα': ObjectId (user_id)})
@staticmethod
deffind_by_username(συλλογή: Συλλογή, όνομα χρήστη: str):
ΕΠΙΣΤΡΟΦΗ collection.find_one({'όνομα χρήστη': όνομα χρήστη})
Ο παραπάνω κώδικας ορίζει α Χρήστης κλάση που χρησιμεύει ως μοντέλο δεδομένων και ορίζει διάφορες μεθόδους για την αλληλεπίδραση με μια συλλογή MongoDB για την εκτέλεση λειτουργιών που σχετίζονται με το χρήστη.
- ο αποθηκεύσετε μέθοδος αποθηκεύει ένα νέο έγγραφο χρήστη με το παρεχόμενο όνομα χρήστη και κωδικό πρόσβασης στη συλλογή MongoDB και επιστρέφει το αναγνωριστικό του εγγράφου που έχει εισαχθεί.
- ο find_by_id και find_by_username Οι μέθοδοι ανακτούν έγγραφα χρήστη από τη συλλογή με βάση το παρεχόμενο αναγνωριστικό χρήστη ή το όνομα χρήστη, αντίστοιχα.
Καθορίστε τις διαδρομές ελέγχου ταυτότητας
- Ας ξεκινήσουμε ορίζοντας τη διαδρομή εγγραφής. Αυτή η διαδρομή θα προσθέσει νέα δεδομένα χρήστη στη συλλογή χρηστών MongoDB. Στον ριζικό κατάλογο, δημιουργήστε ένα νέο routes/user_auth.py αρχείο και τον ακόλουθο κώδικα.
εισαγωγή jwt
από λειτουργικά εργαλεία εισαγωγή αναδιπλώνεται
από φλάσκα εισαγωγή jsonify, request, make_response
από μοντέλα.user_model εισαγωγή Χρήστης
εισαγωγή bcrypt
εισαγωγή osdefregister_routes(εφαρμογή, db):
συλλογή = db.χρήστες
app.config['ΜΥΣΤΙΚΟ ΚΛΕΙΔΙ'] = os.urandom(24)@app.route('/api/register', metoda=['POST'])
defκανω ΕΓΓΡΑΦΗ():
όνομα χρήστη = request.json.get('όνομα χρήστη')
κωδικός πρόσβασης = request.json.get('Κωδικός πρόσβασης')
υπάρχον_χρήστης = User.find_by_username (συλλογή, όνομα χρήστη)
αν υπάρχων χρήστης:
ΕΠΙΣΤΡΟΦΗ jsonify({'μήνυμα': 'Το όνομα χρήστη υπάρχει ήδη!'})
hashed_password = bcrypt.hashpw (password.encode('utf-8'), bcrypt.gensalt())
new_user = Χρήστης (συλλογή, όνομα χρήστη, hashed_password.decode('utf-8'))
user_id = new_user.save()ΕΠΙΣΤΡΟΦΗ jsonify({'μήνυμα': 'Ο χρήστης εγγράφηκε με επιτυχία!', 'ταυτότητα χρήστη': ταυτότητα χρήστη})
- Εφαρμόστε τη λειτουργία σύνδεσης, για να χειριστείτε τη διαδικασία ελέγχου ταυτότητας και να επαληθεύσετε τα διαπιστευτήρια χρήστη. Κάτω από τη διαδρομή εγγραφής, προσθέστε τον ακόλουθο κωδικό.
Το τελικό σημείο σύνδεσης κάνει δύο πράγματα: επαληθεύει τα παρεχόμενα διαπιστευτήρια χρήστη και, μετά τον επιτυχή έλεγχο ταυτότητας, δημιουργεί ένα μοναδικό JWT για αυτόν τον χρήστη. Ορίζει αυτό το διακριτικό ως cookie στην απάντηση, μαζί με ένα ωφέλιμο φορτίο JSON που υποδεικνύει μια επιτυχημένη σύνδεση. Εάν τα διαπιστευτήρια δεν είναι έγκυρα, θα επιστρέψει μια απάντηση JSON για να το υποδείξει.@app.route('/api/login', metoda=['POST'])
defΣύνδεση():
όνομα χρήστη = request.json.get('όνομα χρήστη')
κωδικός πρόσβασης = request.json.get('Κωδικός πρόσβασης')
χρήστης = User.find_by_username (συλλογή, όνομα χρήστη)
αν χρήστης:
αν bcrypt.checkpw (password.encode('utf-8'), χρήστης['Κωδικός πρόσβασης'].encode('utf-8')):
token = jwt.encode({'ταυτότητα χρήστη': str (χρήστης['_ταυτότητα'])}, app.config['ΜΥΣΤΙΚΟ ΚΛΕΙΔΙ'], αλγόριθμος='HS256')
απάντηση = make_response (jsonify({'μήνυμα': 'Επιτυχής σύνδεση!'}))
answer.set_cookie('ένδειξη', διακριτικό)
ΕΠΙΣΤΡΟΦΗ απάντησηΕΠΙΣΤΡΟΦΗ jsonify({'μήνυμα': 'Μη έγκυρο όνομα ή κωδικός'})
- Ορίστε μια συνάρτηση διακοσμητή που επαληθεύει τα JSON Web Tokens (JWT) που διαβιβάζονται μαζί με τα επόμενα αιτήματα API. Προσθέστε τον παρακάτω κώδικα μέσα στο register_routes μπλοκ κώδικα λειτουργίας.
Αυτή η λειτουργία διακοσμητή διασφαλίζει την παρουσία ενός έγκυρου διακριτικού JWT σε επόμενα αιτήματα API. Ελέγχει εάν το διακριτικό λείπει, έχει λήξει ή είναι έγκυρο και επιστρέφει μια κατάλληλη απάντηση JSON εάν είναι.deftoken_required(φά):
@wraps (f)
defδιακοσμημένο(*args, **kwargs):
token = request.cookies.get('ένδειξη')ανδεν ένδειξη:
ΕΠΙΣΤΡΟΦΗ jsonify({'μήνυμα': "Λείπει το διακριτικό!"}), 401δοκιμάστε:
data = jwt.decode (token, app.config['ΜΥΣΤΙΚΟ ΚΛΕΙΔΙ'], αλγόριθμοι=['HS256'])
current_user = User.find_by_id (συλλογή, δεδομένα['ταυτότητα χρήστη'])
εκτός jwt. ExpiredSignatureError:
ΕΠΙΣΤΡΟΦΗ jsonify({'μήνυμα': 'Το token έχει λήξει!'}), 401
εκτός jwt. InvalidTokenError:
ΕΠΙΣΤΡΟΦΗ jsonify({'μήνυμα': 'Μη έγκυρο διακριτικό!'}), 401ΕΠΙΣΤΡΟΦΗ f (current_user, *args, **kwargs)
ΕΠΙΣΤΡΟΦΗ διακοσμημένο
- Τέλος, δημιουργήστε μια προστατευμένη διαδρομή.
@app.route('/api/users', metoda=['GET'])
@token_required
defget_users(τρέχων χρήστης):
χρήστες = λίστα (collection.find({}, {'_ταυτότητα': 0}))
ΕΠΙΣΤΡΟΦΗ jsonify (χρήστες)
Αυτό το τελικό σημείο χειρίζεται τη λογική για την ανάκτηση δεδομένων χρήστη από τη βάση δεδομένων, αλλά απαιτεί από τον πελάτη που στέλνει αιτήματα να συμπεριλάβει ένα έγκυρο διακριτικό για πρόσβαση στα δεδομένα.
Τέλος, εκτελέστε την παρακάτω εντολή για να περιστρέψετε τον διακομιστή ανάπτυξης.
τρέξιμο φιάλης
Για να δοκιμάσετε την εγγραφή, τη σύνδεση και το τελικό σημείο των προστατευμένων χρηστών, μπορείτε να χρησιμοποιήσετε το Postman ή οποιοδήποτε άλλο πρόγραμμα-πελάτη API. Αποστολή αιτημάτων σε http://localhost: 5000/api/και παρατηρήστε τις απαντήσεις για να επαληθεύσετε τη λειτουργικότητα αυτών των τελικών σημείων API.
Είναι ο έλεγχος ταυτότητας με διακριτικό ένα αλάνθαστο μέτρο ασφαλείας;
Τα JSON Web Tokens παρέχουν έναν ισχυρό και αποτελεσματικό τρόπο ελέγχου ταυτότητας των χρηστών για την εφαρμογή ιστού σας. Ωστόσο, είναι σημαντικό να κατανοήσουμε ότι ο έλεγχος ταυτότητας με διακριτικό δεν είναι αλάνθαστος. είναι μόνο ένα κομμάτι ενός μεγαλύτερου παζλ ασφαλείας.
Συνδυάστε τον έλεγχο ταυτότητας διακριτικών με άλλες βέλτιστες πρακτικές ασφάλειας. Θυμηθείτε να παρακολουθείτε συνεχώς και να υιοθετείτε συνεπείς πρακτικές ασφαλείας. θα βελτιώσετε σημαντικά τη συνολική ασφάλεια των εφαρμογών σας Flask.