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?
- JWT’nin Avantajları
- FastAPI Kurulumu
- Gerekli JWT Paketlerinin Kurulumu
- FastAPI’de JWT ile Kimlik Doğrulama
- Örnek FastAPI JWT Uygulaması
- Ek Güvenlik İpuçları
- Sonuç
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:
- Kullanıcının kimlik bilgilerini (kullanıcı adı ve şifre) almak.
- Kullanıcının kimlik bilgilerini veritabanında doğrulamak.
- Doğrulama başarılıysa, bir JWT oluşturmak.
- JWT’yi kullanıcıya göndermek.
- Kullanıcı, sonraki isteklerde JWT’yi `Authorization` başlığında taşır.
- 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.