JSON Web Tokens קלים לשימוש ולניפוי באגים, אך הם גם מציעים חיזוק אבטחה מרשים.

אימות שבור ממשיך להיות פגיעות מתמשכת ביישומי אינטרנט מודרניים - הוא עדיין מדורג גבוה ב-10 סיכוני אבטחת ה-API המובילים של OWASP.

ההשפעות של פגיעות זו יכולות להיות חמורות. הם יכולים להעניק גישה לא מורשית לנתונים רגישים ולפגוע בשלמות המערכת. כדי להבטיח ביעילות גישה מאובטחת ליישומים ולמשאבים שלהם, חיוני שתשתמש במנגנוני אימות חזקים.

גלה כיצד תוכל ליישם אימות משתמשים ב-Flask באמצעות JSON Web Tokens (JWT), שיטה פופולרית ויעילה מבוססת אסימון.

אימות מבוסס אסימון באמצעות JSON Web Tokens

אימות מבוסס אסימון משתמש במחרוזת מוצפנת של תווים כדי לאמת ולאשר גישה למערכת או למשאב. אתה יכול ליישם סוג זה של אימות באמצעות שיטות שונות, כולל אסימוני הפעלה, מפתחות API ואסימוני אינטרנט של JSON.

JWTs, במיוחד, מציעים גישה מאובטחת וקומפקטית להעברת אישורי המשתמשים הנדרשים בין יישומים ושרתים בצד הלקוח.

JWT מורכב משלושה מרכיבים עיקריים: הכותרת, המטען והחתימה. הכותרת מכילה מטא נתונים לגבי האסימון, כולל אלגוריתם הגיבוב המשמש לקידוד האסימון.

המטען מכיל את אישורי המשתמש בפועל, כגון מזהה משתמש והרשאות. לבסוף, החתימה מבטיחה את תוקפו של האסימון על ידי אימות תוכנו באמצעות מפתח סודי.

instagram viewer

באמצעות JWTs, אתה יכול לאמת משתמשים ולאחסן נתוני הפעלה הכל בתוך האסימון עצמו.

הגדר פרויקט Flask ומסד נתונים של MongoDB

כדי להתחיל, צור ספריית פרויקט חדשה באמצעות מסוף:

mkdir flask-project
cd flask-project

לאחר מכן, התקן virtualenv, כדי ליצור סביבת פיתוח וירטואלית מקומית עבור פרויקט Flask שלך.

virtualenv venv

לבסוף, הפעל את הסביבה הוירטואלית.

# יוניקס או MacOS: 
מקור venv/bin/activate

# חלונות:
.\venv\Scripts\להפעיל

אתה יכול למצוא את הקוד של הפרויקט הזה בזה מאגר GitHub.

התקן את החבילות הנדרשות

בספריית השורש של תיקיית הפרויקט שלך, צור חדש requirements.txt קובץ, והוסף את התלות הללו עבור הפרויקט:

בקבוק
pyjwt
python-dotenv
pymongo
bcrypt

לבסוף, הפעל את הפקודה למטה כדי להתקין את החבילות. תוודא שיש לך צִפצוּף (מנהל חבילות) מותקן; אם לא, התקן אותו במערכת Windows, Mac או Linux שלך.

pip install -r requirements.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 החיבור המסופק. לאחר מכן הוא יוצר חדש משתמשים אוסף אם הוא לא קיים, ומחזיר את מופע מסד הנתונים המתאים.

צור את שרת האינטרנט Flask

כאשר מסד הנתונים מוגדר, קדימה, וצור קובץ app.py קובץ בספריית השורש של תיקיית הפרויקט, והוסף את הקוד הבא כדי ליצור מופע של היישום Flask.

מ בקבוק יְבוּא בקבוק
מ routes.user_auth יְבוּא register_routes
מ utils.db יְבוּא connect_to_mongodb
יְבוּא OS
מ dotenv יְבוּא load_dotenv

app = Flask (__name__)
load_dotenv()

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

register_routes (אפליקציה, db)

אם __שם__ == '__רָאשִׁי__':
app.run (debug=נָכוֹן)

צור את נקודות הקצה של Authentication API

כדי ליישם אימות משתמשים ביישום Flask שלך, חיוני להגדיר את נקודות הקצה הדרושות של API המטפלות בפעולות הקשורות לאימות.

עם זאת, ראשית, הגדר את המודל עבור נתוני המשתמשים. כדי לעשות זאת, צור חדש model/user_model.py הקובץ בספריית השורש, והוסף את הקוד הבא.

מ pymongo.collection יְבוּא אוסף
מ bson.objectid יְבוּא ObjectId

מעמדמִשׁתַמֵשׁ:
def__init__(עצמי, אוסף: אוסף, שם משתמש: str, סיסמה: str):
self.collection = אוסף
self.username = שם משתמש
self.password = סיסמה
defלהציל(עצמי):
user_data = {
'שם משתמש': self.username,
'סיסמה': סיסמה עצמית
}
result = self.collection.insert_one (user_data)
לַחֲזוֹר str (result.inserted_id)

@staticmethod
deffind_by_id(אוסף: Collection, user_id: str):
לַחֲזוֹר collection.find_one({'_תְעוּדַת זֶהוּת': ObjectId (user_id)})

@staticmethod
deffind_by_username(אוסף: אוסף, שם משתמש: str):
לַחֲזוֹר collection.find_one({'שם משתמש': שם משתמש})

הקוד למעלה מציין את א מִשׁתַמֵשׁ מחלקה המשמשת כמודל נתונים ומגדירה מספר שיטות לאינטראקציה עם אוסף MongoDB לביצוע פעולות הקשורות למשתמש.

  1. ה להציל השיטה שומרת מסמך משתמש חדש עם שם המשתמש והסיסמה שסופקו לאוסף MongoDB ומחזירה את המזהה של המסמך שהוכנס.
  2. ה find_by_id ו find_by_username שיטות מאחזרות מסמכי משתמש מהאוסף בהתבסס על מזהה המשתמש או שם המשתמש שסופקו, בהתאמה.

הגדר את נתיבי האימות

  1. נתחיל בהגדרת מסלול הרישום. מסלול זה יוסיף נתוני משתמשים חדשים לאוסף משתמשי MongoDB. בספריית השורש, צור חדש routes/user_auth.py קובץ, והקוד הבא.
    יְבוּא jwt
    מ functools יְבוּא עוטפת
    מ בקבוק יְבוּא jsonify, request, make_response
    מ models.user_model יְבוּא מִשׁתַמֵשׁ
    יְבוּא bcrypt
    יְבוּא OS

    defregister_routes(אפליקציה, db):
    אוסף = db.users
    app.config['מפתח סודי'] = os.urandom(24)

    @app.route('/api/register', methods=['POST'])
    defהירשם():

    שם משתמש = request.json.get('שם משתמש')
    סיסמה = request.json.get('סיסמה')

    exist_user = 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({'הוֹדָעָה': 'משתמש נרשם בהצלחה!', 'זהות המשתמש': זהות המשתמש})

  2. יישם את פונקציונליות הכניסה, כדי לטפל בתהליך האימות ולאמת את אישורי המשתמש. תחת מסלול הרישום, הוסף את הקוד הבא.
     @app.route('/api/login', methods=['POST'])
    defהתחברות():
    שם משתמש = request.json.get('שם משתמש')
    סיסמה = request.json.get('סיסמה')
    user = User.find_by_username (אוסף, שם משתמש)
    אם מִשׁתַמֵשׁ:
    אם bcrypt.checkpw (password.encode('utf-8'), משתמש['סיסמה'].לְהַצְפִּין('utf-8')):
    token = jwt.encode({'זהות המשתמש': str (משתמש['_תְעוּדַת זֶהוּת'])}, app.config['מפתח סודי'], אלגוריתם='HS256')

    response = make_response (jsonify({'הוֹדָעָה': 'התחברת בהצלחה!'}))
    response.set_cookie('אֲסִימוֹן', אסימון)
    לַחֲזוֹר תְגוּבָה

    לַחֲזוֹר jsonify({'הוֹדָעָה': 'שם משתמש או סיסמה לא חוקיים'})

    נקודת הקצה של ההתחברות עושה שני דברים: היא מאמתת את אישורי המשתמש שסופקו, ולאחר אימות מוצלח, היא מייצרת JWT ייחודי עבור אותו משתמש. הוא מגדיר את האסימון הזה כקובץ Cookie בתגובה, יחד עם מטען JSON המציין כניסה מוצלחת. אם האישורים אינם חוקיים, הוא יחזיר תגובת JSON כדי לציין זאת.
  3. הגדר פונקציית עיצוב המאמתת את אסימוני האינטרנט של JSON (JWTs) שהועברו יחד עם בקשות API עוקבות. הוסף את הקוד למטה בתוך register_routes בלוק קוד פונקציה.
    deftoken_required(ו):
    עטיפה @(ו)
    defמְעוּטָר(*ארגס, **קווארגס):
    token = request.cookies.get('אֲסִימוֹן')

    אםלֹא אֲסִימוֹן:
    לַחֲזוֹר jsonify({'הוֹדָעָה': 'חסר אסימון!'}), 401

    לְנַסוֹת:
    data = jwt.decode (אסימון, app.config['מפתח סודי'], אלגוריתמים=['HS256'])
    current_user = User.find_by_id (אוסף, נתונים['זהות המשתמש'])
    מלבד jwt. ExpiredSignatureError:
    לַחֲזוֹר jsonify({'הוֹדָעָה': 'פג תוקפו של האסימון!'}), 401
    מלבד jwt. InvalidTokenError:
    לַחֲזוֹר jsonify({'הוֹדָעָה': 'אסימון לא חוקי!'}), 401

    לַחֲזוֹר f (משתמש_נוכחי, *args, **kwargs)

    לַחֲזוֹר מְעוּטָר

    פונקציית עיצוב זה מבטיחה את נוכחותו של אסימון JWT חוקי בבקשות API עוקבות. הוא בודק אם האסימון חסר, פג תוקפו או חוקי, ומחזיר תגובת JSON מתאימה אם כן.
  4. לבסוף, צור מסלול מוגן.
     @app.route('/api/users', methods=['GET'])
    @token_required
    defget_users(משתמש נוכחי):
    משתמשים = רשימה (collection.find({}, {'_תְעוּדַת זֶהוּת': 0}))
    לַחֲזוֹר jsonify (משתמשים)

נקודת קצה זו מטפלת בלוגיקה של אחזור נתוני משתמש ממסד הנתונים, אך היא דורשת מהלקוח השולח בקשות לכלול אסימון חוקי כדי לגשת לנתונים.

לבסוף, הפעל את הפקודה למטה כדי לסובב את שרת הפיתוח.

ריצת בקבוק

כדי לבדוק את הרישום, הכניסה ונקודת הקצה של המשתמשים המוגנים, אתה יכול להשתמש ב-Postman או בכל לקוח API אחר. שלח בקשות ל http://localhost: 5000/api/וצפה בתגובות כדי לאמת את הפונקציונליות של נקודות קצה אלו של API.

האם אימות אסימון הוא אמצעי אבטחה חסין תקלות?

JSON Web Tokens מספקים דרך חזקה ויעילה לאימות משתמשים עבור אפליקציית האינטרנט שלך. עם זאת, חשוב להבין שאימות אסימון אינו חסין תקלות; זה רק חלק אחד בפאזל אבטחה גדול יותר.

שלב אימות אסימון עם שיטות אבטחה מומלצות אחרות. זכור לפקח באופן רציף, ולאמץ נוהלי אבטחה עקביים; אתה תשפר משמעותית את האבטחה הכוללת של יישומי Flask שלך.