FastAPI ile Güvenli API’ler: JWT Entegrasyonu

FastAPI ile Güvenli API’ler: JSON Web Token (JWT) Entegrasyonu

Günümüzde web uygulamalarının güvenliği, kullanıcı verilerinin korunması ve yetkisiz erişimin engellenmesi açısından kritik bir öneme sahiptir. FastAPI, modern web API’leri oluşturmak için kullanılan yüksek performanslı bir Python framework’üdür. JSON Web Token (JWT), API güvenliğini sağlamak için yaygın olarak kullanılan bir yöntemdir. Bu makalede, FastAPI uygulamalarında JWT’nin nasıl kullanılacağını adım adım inceleyeceğiz.

İçindekiler

JSON Web Token (JWT) Nedir?

JSON Web Token (JWT), taraflar arasında güvenli bir şekilde bilgi alışverişi yapmak için kullanılan açık bir standarttır (RFC 7519). JWT, JSON nesnesi olarak temsil edilen verileri içerir ve dijital olarak imzalanır. İmzalama işlemi, verilerin bütünlüğünü ve kaynağını doğrulamak için kullanılır. JWT’ler genellikle yetkilendirme ve bilgi paylaşımı için kullanılır.

JWT’nin Avantajları

  • Basitlik: JWT, JSON formatında olduğu için kolayca oluşturulabilir ve ayrıştırılabilir.
  • Ölçeklenebilirlik: JWT’ler, sunucu tarafında oturum bilgilerini saklamadan kimlik doğrulama işlemini gerçekleştirdiği için ölçeklenebilir bir çözümdür.
  • Çoklu Platform Desteği: JWT, farklı programlama dillerinde ve platformlarda kullanılabilir.
  • Güvenlik: JWT, dijital olarak imzalandığı için verilerin bütünlüğünü ve kaynağını doğrular.

FastAPI Kurulumu

FastAPI’yi kurmak için aşağıdaki komutu kullanabilirsiniz:

pip install fastapi uvicorn

Bu komut, FastAPI ve bir ASGI sunucusu olan Uvicorn’u yükler. Uvicorn, FastAPI uygulamalarını çalıştırmak için gereklidir.

Gerekli JWT Paketlerinin Kurulumu

FastAPI’de JWT kullanmak için `python-jose` ve `passlib` paketlerini yüklemeniz gerekir:

pip install python-jose[cryptography] passlib
  • `python-jose`: JWT oluşturmak ve doğrulamak için kullanılır.
  • `passlib`: Şifreleri güvenli bir şekilde saklamak için kullanılır.

FastAPI’de JWT ile Kimlik Doğrulama

FastAPI’de JWT ile kimlik doğrulama süreci aşağıdaki adımları içerir:

  1. Kullanıcının kimlik bilgilerini (kullanıcı adı ve şifre) almak.
  2. Kullanıcının kimlik bilgilerini veritabanında doğrulamak.
  3. Doğrulama başarılıysa, bir JWT oluşturmak.
  4. JWT’yi kullanıcıya göndermek.
  5. Kullanıcı, sonraki isteklerde JWT’yi `Authorization` başlığında taşır.
  6. Sunucu, JWT’yi doğrular ve kullanıcıya erişim izni verir.

Şifre Oluşturma ve Saklama

Kullanıcı şifrelerini veritabanında düz metin olarak saklamak güvenli değildir. Şifreleri güvenli bir şekilde saklamak için `passlib` kütüphanesini kullanabilirsiniz:


from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def hash_password(password: str) -> str:
    return pwd_context.hash(password)

def verify_password(password: str, hashed_password: str) -> bool:
    return pwd_context.verify(password, hashed_password)

Bu kod, `bcrypt` algoritmasıyla şifreleri hash’ler ve doğrular.

JWT Token Oluşturma

JWT token oluşturmak için `python-jose` kütüphanesini kullanabilirsiniz:


import jwt
from datetime import datetime, timedelta

SECRET_KEY = "YOUR_SECRET_KEY"  # Güvenli bir anahtar kullanın
ALGORITHM = "HS256"

def create_access_token(data: dict, expires_delta: 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

Bu kod, kullanıcı bilgilerini ve bir son kullanma tarihini içeren bir JWT token oluşturur.

JWT Token Doğrulama

JWT token’ı doğrulamak için aşağıdaki kodu kullanabilirsiniz:


from fastapi import HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from typing import Optional

security = HTTPBearer()

async def get_current_user(credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)):
    if credentials is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Kimlik bilgileri doğrulanamadı",
            headers={"WWW-Authenticate": "Bearer"},
        )
    token = credentials.credentials
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Kimlik bilgileri doğrulanamadı",
                headers={"WWW-Authenticate": "Bearer"},
            )
        # Burada kullanıcıyı veritabanından çekebilirsiniz
        # user = get_user(username=username)
        # if user is None:
        #     raise HTTPException(
        #         status_code=status.HTTP_401_UNAUTHORIZED,
        #         detail="Kimlik bilgileri doğrulanamadı",
        #         headers={"WWW-Authenticate": "Bearer"},
        #     )
        return {"username": username}
    except jwt.JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Kimlik bilgileri doğrulanamadı",
            headers={"WWW-Authenticate": "Bearer"},
        )

Bu kod, `Authorization` başlığındaki JWT token’ı doğrular ve kullanıcı bilgilerini döndürür.

Örnek FastAPI JWT Uygulaması

Aşağıdaki kod, basit bir FastAPI uygulamasında JWT’nin nasıl kullanılacağını gösterir:


from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from datetime import timedelta

app = FastAPI()

@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    # Kullanıcıyı doğrula (örneğin, veritabanında)
    user = authenticate_user(form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Yanlış kullanıcı adı veya şifre",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=15)
    access_token = create_access_token(
        data={"sub": user.username},
        expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

@app.get("/items/")
async def read_items(current_user: dict = Depends(get_current_user)):
    return {"message": f"Merhaba, {current_user['username']}!"}

# Yardımcı fonksiyonlar (authenticate_user, get_user) ve JWT ile ilgili fonksiyonlar (create_access_token, get_current_user) yukarıda tanımlanmıştır.

Bu uygulama, `/token` endpoint’inde kullanıcıdan kullanıcı adı ve şifre alır, kimlik bilgilerini doğrular ve bir JWT token oluşturur. `/items/` endpoint’i, JWT ile kimlik doğrulaması gerektirir. Sadece geçerli bir JWT token’ı olan kullanıcılar bu endpoint’e erişebilir.

Ek Güvenlik İpuçları

  • Güçlü bir SECRET_KEY kullanın: SECRET_KEY, JWT’yi imzalamak için kullanılır. Güçlü ve tahmin edilmesi zor bir anahtar kullanmak, token’ın güvenliğini artırır.
  • Son kullanma tarihi (expiration time) belirleyin: JWT’lerin sonsuza kadar geçerli olmasını önlemek için bir son kullanma tarihi belirleyin. Bu, token’ın çalınması durumunda potansiyel zararı sınırlar.
  • HTTPS kullanın: JWT’leri iletirken HTTPS kullanmak, token’ın ele geçirilmesini önler.
  • Token’ları güvenli bir şekilde saklayın: Token’ları tarayıcıda güvenli bir şekilde saklamak için `HttpOnly` ve `Secure` bayraklarını kullanın.
  • Refresh token kullanın: Uzun süreli oturumlar için refresh token kullanmak, kullanıcıların sık sık oturum açmasını önler ve güvenliği artırır.

Sonuç

Bu makalede, FastAPI uygulamalarında JWT’nin nasıl kullanılacağını adım adım inceledik. JWT, API güvenliğini sağlamak için etkili bir yöntemdir. Ancak, JWT’nin doğru şekilde kullanılması ve ek güvenlik önlemlerinin alınması önemlidir. Bu makaledeki bilgileri kullanarak, FastAPI uygulamalarınızda güvenli ve ölçeklenebilir API’ler oluşturabilirsiniz.

Leave A Comment

Your email address will not be published. Required fields are marked *