ویژگی تصویر

احراز هویت JWT در FastAPI

  /  پایتون   /  احراز هویت JWT در FastAPI
بنر تبلیغاتی الف

FastAPI یک فریمورک پایتونی قوی برای ساخت APIهای مدرن و سریع است. برای مدیریت احراز هویت کاربران، JWT (JSON Web Token) یک روش متداول و امن است. در این مقاله به بررسی نحوه پیاده‌سازی JWT در FastAPI می‌پردازیم.

چرا JWT؟

JWT یک استاندارد باز برای احراز هویت کاربران است که اطلاعاتی در قالب JSON در داخل توکن قرار می‌دهد. این توکن به صورت کاملاً امن و بدون نیاز به ذخیره‌سازی در سرور قابل اعتبارسنجی است.

  • عدم نیاز به ذخیره سشن در سرور
  • قابلیت توزیع در محیط‌های چند ماژولی
  • امنیت بالا با استفاده از توکن‌های معتبر

ساختار JWT

JWT شامل سه بخش اصلی است:

  • Header: نوع توکن و الگوریتم رمزنگاری
  • Payload: اطلاعات کاربری (مثل username، role)
  • Signature: برای اعتبارسنجی محتوا

نصب و راه‌اندازی پکیج‌ها

ابتدا نیازمند افزودن پکیج‌های زیر هستیم:

pip install fastapi uvicorn python-jose[cryptography] passlib[bcrypt] python-dotenv

این دستورات پکیج‌های لازم برای FastAPI، رمزنگاری، و مدیریت کلمه عبور را نصب می‌کنند.

پیاده‌سازی ساده JWT در FastAPI

در این بخش، یک ساختار پایه برای احراز هویت با JWT را پیاده می‌کنیم:

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta
from typing import Optional

SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# داده‌های مثال برای کاربران
fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "john@example.com",
        "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW",
        "disabled": False,
    }
}

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)

def authenticate_user(db, username: str, password: str):
    user = get_user(db, username)
    if not user:
        return False
    if not verify_password(password, user.hashed_password):
        return False
    return user

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

@app.post("/token")
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
    user = authenticate_user(fake_users_db, form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user

در این کد، ما ابتدا یک توکن JWT با استفاده از مقدار username ایجاد کرده‌ایم. همچنین، کاربران به صورت دمو در یک دیکشنری ذخیره شده‌اند. اگر اطلاعات ورود صحیح باشد، توکنی برای کاربر ارسال می‌شود.

استاندارد‌سازی و بهترین روش‌ها

در پیاده‌سازی JWT در FastAPI باید به نکات زیر توجه کنید:

نکتهتوضیح
استفاده از توکن‌های موقتتوکن‌های JWT باید مدت زمان محدودی داشته باشند تا امنیت کاربر را حفظ کنند.
رمزگذاری پسوردپسورد‌ها باید همیشه با استفاده از الگوریتم‌های معتبر رمزنگاری شوند.
استفاده از SECRET_KEYSECRET_KEY نباید در کد قابل دسترس باشد. باید در متغیرهای محیطی ذخیره شود.

نحوه استفاده از توکن در درخواست‌ها

پس از احراز هویت، کاربر باید توکن را در هدر درخواست‌های بعدی قرار دهد:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

این توکن در هدر Authorization قرار می‌گیرد و سرور آن را اعتبارسنجی می‌کند.

پیاده‌سازی پیشرفته با استفاده از FastAPI Security

FastAPI امکانات قوی برای مدیریت سطوح دسترسی فراهم می‌کند:

from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import Depends

security = HTTPBearer()

async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
    token = credentials.credentials
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
        return User(username=username)
    except JWTError:
        raise credentials_exception

در این کد، ما یک وابستگی برای بازیابی کاربر فعلی از توکن JWT تعریف کرده‌ایم. این روش به شما اجازه می‌دهد هر endpoint را فقط برای کاربران معتبر فعال کنید.

بهبود و امنیت

برای افزایش امنیت، باید:

  • توکن‌ها را با استفاده از HTTPS منتقل کنید
  • استفاده از الگوریتم‌های قوی برای رمزنگاری (مثل RS256)
  • به‌روزرسانی SECRET_KEY به صورت منظم
  • توکن‌های دوباره استفاده شده را مسدود کنید (Token Blacklisting)

جمع‌بندی

JWT در FastAPI ابزار قدرتمندی برای مدیریت احراز هویت است. با پیاده‌سازی صحیح و بهره‌گیری از ابزارهای FastAPI، می‌توانید از توکن‌های امن و قابل‌اعتماد استفاده کنید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: