خبر و ترفند روز

خبر و ترفند های روز را اینجا بخوانید!

نحوه پیاده سازی احراز هویت کاربر در فلاسک با استفاده از JWT

استفاده و اشکال زدایی از توکن های وب JSON آسان است، اما امنیت قابل توجهی را نیز ارائه می دهند.

احراز هویت شکسته همچنان یک آسیب‌پذیری دائمی در برنامه‌های کاربردی وب مدرن است – هنوز هم در رتبه‌های بالایی در 10 خطر امنیتی برتر API OWASP قرار دارد.

اثرات این آسیب پذیری می تواند شدید باشد. آنها می توانند به داده های حساس دسترسی غیرمجاز بدهند و یکپارچگی سیستم را به خطر بیندازند. برای اطمینان از دسترسی ایمن به برنامه‌ها و منابع آنها، استفاده از مکانیزم‌های احراز هویت قوی ضروری است.

دریابید که چگونه می توانید احراز هویت کاربر را در Flask با استفاده از JSON Web Tokens (JWT)، یک روش مبتنی بر توکن محبوب و موثر پیاده سازی کنید.

احراز هویت مبتنی بر توکن با استفاده از توکن های وب JSON

احراز هویت مبتنی بر توکن از یک رشته رمزگذاری شده از کاراکترها برای تأیید اعتبار و مجوز دسترسی به یک سیستم یا منبع استفاده می کند. شما می توانید این نوع احراز هویت را با استفاده از روش های مختلف، از جمله نشانه های جلسه، کلیدهای API و توکن های وب JSON پیاده سازی کنید.

JWT ها، به ویژه، یک رویکرد امن و فشرده برای انتقال اعتبار کاربران مورد نیاز بین برنامه های کاربردی سمت مشتری و سرورها ارائه می دهند.

نمونه ای از توکن JWT کدگذاری شده در سمت چپ و نسخه رمزگشایی شده توکن که اجزای جداگانه را در سمت راست نشان می دهد.

یک JWT از سه جزء اصلی تشکیل شده است: هدر، محموله و امضا. هدر حاوی ابرداده در مورد توکن، از جمله الگوریتم هش مورد استفاده برای رمزگذاری توکن است.

محموله حاوی اطلاعات کاربری واقعی، مانند شناسه کاربری و مجوزها است. در نهایت، امضا با تأیید محتویات آن با استفاده از یک کلید مخفی، اعتبار توکن را تضمین می کند.

با استفاده از JWT ها، می توانید کاربران را احراز هویت کنید و داده های جلسه را همه در خود توکن ذخیره کنید.

یک پروژه Flask و یک پایگاه داده MongoDB راه اندازی کنید

برای شروع، یک فهرست پروژه جدید با استفاده از ترمینال ایجاد کنید:

mkdir flask-project
cd flask-project

سپس virtualenv را نصب کنید تا یک محیط توسعه مجازی محلی برای پروژه Flask خود ایجاد کنید.

virtualenv venv

در نهایت محیط مجازی را فعال کنید.

# Unix or MacOS:
source venv/bin/activate

# Windows:
.\venv\Scripts\activate

می توانید کد این پروژه را در این مخزن GitHub پیدا کنید.

بسته های مورد نیاز را نصب کنید

در دایرکتوری اصلی پوشه پروژه خود، یک فایل requires.txt جدید ایجاد کنید و این وابستگی ها را برای پروژه اضافه کنید:

flask
pyjwt
python-dotenv
pymongo
bcrypt

در نهایت دستور زیر را برای نصب بسته ها اجرا کنید. مطمئن شوید که پیپ (مدیر بسته) را نصب کرده اید. اگر نه، آن را روی سیستم ویندوز، مک یا لینوکس خود نصب کنید.

pip install -r requirements.txt

یک پایگاه داده MongoDB ایجاد کنید

پیش بروید و یک پایگاه داده MongoDB ایجاد کنید. می‌توانید یک پایگاه داده محلی MongoDB راه‌اندازی کنید، یا یک خوشه در MongoDB Atlas، یک سرویس MongoDB مبتنی بر ابر ایجاد کنید.

مطلب مرتبط:   نحوه تنظیم و استفاده از تایید دو مرحله ای در واتس اپ

هنگامی که پایگاه داده را ایجاد کردید، URI اتصال را کپی کنید، یک فایل .env در دایرکتوری ریشه پروژه خود ایجاد کنید و آن را به صورت زیر اضافه کنید:

MONGO_URI="<insert-connection-uri>"

در نهایت، اتصال پایگاه داده را از برنامه Flask خود پیکربندی کنید. یک فایل utils/db.py جدید در دایرکتوری ریشه پروژه خود با این کد ایجاد کنید:

from pymongo import MongoClient

def connect_to_mongodb(mongo_uri):
    client = MongoClient(mongo_uri)
    db = client.get_database("users")
    return db

این تابع با استفاده از URI اتصال ارائه شده با پایگاه داده MongoDB ارتباط برقرار می کند. سپس یک مجموعه کاربران جدید در صورت عدم وجود ایجاد می کند و نمونه پایگاه داده مربوطه را برمی گرداند.

وب سرور Flask را ایجاد کنید

با پیکربندی پایگاه داده، ادامه دهید، و یک فایل app.py در دایرکتوری ریشه پوشه پروژه ایجاد کنید و کد زیر را برای ایجاد یک نمونه از برنامه Flask اضافه کنید.

from flask import Flask
from routes.user_auth import register_routes
from utils.db import connect_to_mongodb
import os
from dotenv import load_dotenv

app = Flask(__name__)
load_dotenv()

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

register_routes(app, db)

if __name__ == '__main__':
    app.run(debug=True)

Authentication API Endpoints را ایجاد کنید

برای پیاده سازی احراز هویت کاربر در برنامه Flask خود، تعیین نقاط پایانی API ضروری است که عملیات مربوط به احراز هویت را مدیریت می کند.

با این حال، ابتدا مدلی را برای داده های کاربران تعریف کنید. برای انجام این کار، یک فایل model/user_model.py جدید در پوشه اصلی ایجاد کنید و کد زیر را اضافه کنید.

from pymongo.collection import Collection
from bson.objectid import ObjectId

class User:
    def __init__(self, collection: Collection, username: str, password: str):
        self.collection = collection
        self.username = username
        self.password = password
    def save(self):
        user_data = {
            'username': self.username,
            'password': self.password
        }
        result = self.collection.insert_one(user_data)
        return str(result.inserted_id)

@staticmethod
    def find_by_id(collection: Collection, user_id: str):
        return collection.find_one({'_id': ObjectId(user_id)})

@staticmethod
    def find_by_username(collection: Collection, username: str):
        return collection.find_one({'username': username})

کد بالا یک کلاس User را مشخص می کند که به عنوان یک مدل داده عمل می کند و چندین روش را برای تعامل با مجموعه MongoDB برای انجام عملیات مربوط به کاربر تعریف می کند.

  1. روش ذخیره یک سند کاربر جدید را با نام کاربری و رمز عبور ارائه شده در مجموعه MongoDB ذخیره می کند و شناسه سند درج شده را برمی گرداند.
  2. متدهای find_by_id و find_by_username به ترتیب اسناد کاربر را بر اساس شناسه یا نام کاربری ارائه شده از مجموعه بازیابی می کنند.
مطلب مرتبط:   معماری MVT جنگو توضیح داده شد

مسیرهای احراز هویت را تعریف کنید

  1. بیایید با تعریف مسیر ثبت نام شروع کنیم. این مسیر داده های کاربر جدیدی را به مجموعه کاربران MongoDB اضافه می کند. در پوشه اصلی، یک فایل routes/user_auth.py جدید و کد زیر ایجاد کنید. import jwtfrom functools import wrapsfrom flask import jsonify, request, make_responsefrom models.user_model import وارد کردن Userimport bcryptimport osdef register_routes(app, db):    collection = db.users    app.config [‘SECRET_4) = SECRET_KE. (‘/api/register’, method=[‘POST’])    def register():                username = request.json.get(‘username’)        password = request.json.get(‘password’)                     (مجموعه، نام کاربری)        درصورت موجود_user:             بازگردانید jsonify({‘پیام’: ‘نام کاربری از قبل وجود دارد!’})              hashed_password = bcrypt.hashpw. (‘tcrypt.enco) new_user = کاربر (مجموعه، نام کاربری، hashed_password.decode(‘utf-8’))        user_id = new_user.save()        return jsonify({‘message’: ‘کاربر با موفقیت ثبت شد!’، ‘user_id’: user_id})
  2. برای مدیریت فرآیند احراز هویت و تأیید اعتبار کاربر، عملکرد ورود به سیستم را اجرا کنید. در مسیر ثبت نام، کد زیر را اضافه کنید. @app.route(‘/api/login’, method=[‘POST’])    def login():        username = request.json.get(‘username’)        password = request.json.get(‘password’)        username = نام کاربری. ({‘user_id’: str(user[‘_id’])}، app.config[‘SECRET_KEY’], algorithm=’HS256′)                                           response = make_response(jsonify(‘)پیام موفقیت‌آمیز’}! )                 response.set_cookie(‘token’, token)                  return answer          return jsonify ({‘message’: ‘Invalid username or password, ‘Invalid username or password’) دو کار را انجام می دهد که پس از ورود به سیستم، یک نقطه پایانی تایید شده است. تولید می کند یک JWT منحصر به فرد برای آن کاربر. این نشانه را به عنوان یک کوکی در پاسخ تنظیم می کند، همراه با یک بار JSON که نشان دهنده ورود موفقیت آمیز است. اگر اعتبارنامه نامعتبر باشد، یک پاسخ JSON برای نشان دادن آن برمی‌گرداند.
  3. یک تابع تزئینی تعریف کنید که توکن‌های وب JSON (JWT) را به همراه درخواست‌های API بعدی تأیید می‌کند. کد زیر را در بلوک کد تابع register_routes اضافه کنید. def token_required (f): wraps (f) def dectorated (*args ، ** kwargs): token = درخواست. cookies.get (‘token’) اگر نشانه نیست: jsonify ({“پیام”: “توکن از دست رفته است !’})، 401             سعی کنید:                          data = jwt.decode(token, app.config[‘SECRET_KEY’], algorithms=[‘HS256’] = User-color-id) [‘user_id’])             به جز jwt E !’})، 401             بازگشت f(current_user، *args ، **kwargs)         بازگشت تزئین شده این عملکرد تزئینی وجود یک نشانه JWT معتبر را در درخواست‌های API بعدی تضمین می‌کند. بررسی می‌کند که آیا توکن مفقود، منقضی شده یا معتبر است یا خیر، و در صورت وجود، پاسخ JSON مناسب را برمی‌گرداند.
  4. در نهایت یک مسیر محافظت شده ایجاد کنید. @app.route(‘/api/users’, method=[‘GET’]) @token_required    def get_users(current_user):        users = list(collection.find({}, {‘_id’: 0}))        return json (کاربران)

import jwt
from functools import wraps
from flask import jsonify, request, make_response
from models.user_model import User
import bcrypt
import os


def register_routes(app, db):
    collection = db.users
    app.config['SECRET_KEY'] = os.urandom(24)

@app.route('/api/register', methods=['POST'])
    def register():
        
        username = request.json.get('username')
        password = request.json.get('password')
        
        existing_user = User.find_by_username(collection, username)
        if existing_user:
            return jsonify({'message': 'Username already exists!'})
      
        hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
        new_user = User(collection, username, hashed_password.decode('utf-8'))
        user_id = new_user.save()

        return jsonify({'message': 'User registered successfully!', 'user_id': user_id})

@app.route('/api/login', methods=['POST'])
    def login():
        username = request.json.get('username')
        password = request.json.get('password')
        user = User.find_by_username(collection, username)
        if user:
            if bcrypt.checkpw(password.encode('utf-8'), user['password'].encode('utf-8')):
                token = jwt.encode({'user_id': str(user['_id'])}, app.config['SECRET_KEY'], algorithm='HS256')
          
                response = make_response(jsonify({'message': 'Login successful!'}))
                response.set_cookie('token', token)
                return response

        return jsonify({'message': 'Invalid username or password'})

    def token_required(f):
@wraps(f)
        def decorated(*args, **kwargs):
            token = request.cookies.get('token')

            if not token:
                return jsonify({'message': 'Token is missing!'}), 401

            try:
                data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
                current_user = User.find_by_id(collection, data['user_id'])
            except jwt.ExpiredSignatureError:
                return jsonify({'message': 'Token has expired!'}), 401
            except jwt.InvalidTokenError:
                return jsonify({'message': 'Invalid token!'}), 401

            return f(current_user, *args, **kwargs)

        return decorated

@app.route('/api/users', methods=['GET'])
@token_required
    def get_users(current_user):
        users = list(collection.find({}, {'_id': 0}))
        return jsonify(users)

این نقطه پایانی منطق بازیابی داده‌های کاربر از پایگاه داده را کنترل می‌کند، اما از کلاینتی که درخواست‌ها را ارسال می‌کند می‌خواهد یک نشانه معتبر برای دسترسی به داده‌ها داشته باشد.

مطلب مرتبط:   Atlas VPN رایگان و عالی برای جریان است، اما آیا از حریم خصوصی شما محافظت می کند؟

در نهایت دستور زیر را برای چرخش سرور توسعه اجرا کنید.

flask run

برای آزمایش ثبت نام، ورود به سیستم و نقطه پایانی کاربران محافظت شده، می توانید از Postman یا هر سرویس گیرنده API دیگری استفاده کنید. درخواست ها را به http://localhost:5000/api/ ارسال کنید و پاسخ ها را برای تأیید عملکرد این نقاط پایانی API مشاهده کنید.

آیا احراز هویت توکن یک اقدام امنیتی بدون خطا است؟

JSON Web Tokens یک راه قوی و موثر برای احراز هویت کاربران برای برنامه وب شما ارائه می دهد. با این حال، درک این نکته مهم است که احراز هویت توکن بی‌خطا نیست. این تنها یک تکه از یک پازل امنیتی بزرگتر است.

احراز هویت توکن را با سایر بهترین روش های امنیتی ترکیب کنید. به یاد داشته باشید که به طور مداوم نظارت داشته باشید و شیوه های امنیتی سازگار را اتخاذ کنید. امنیت کلی برنامه های Flask خود را به میزان قابل توجهی افزایش خواهید داد.