احراز هویت با JWT در GraphQL و FastAPI
یکی از رایجترین روشهای احراز هویت در GraphQL استفاده از JWT (JSON Web Token) است. در این روش، پس از ورود موفق کاربر، سرور یک توکن JWT ایجاد میکند و کاربر در درخواستهای بعدی آن را به هدر HTTP اضافه میکند.
۱. نصب کتابخانههای مورد نیاز
pip install pyjwt passlib[bcrypt] fastapi
۲. ایجاد توکن JWT
# utils/jwt.py
import jwt
from datetime import datetime, timedelta
SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
token = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return token
def decode_access_token(token: str):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload
except jwt.ExpiredSignatureError:
raise Exception("Token expired")
except jwt.InvalidTokenError:
raise Exception("Invalid token")
۳. اضافه کردن Dependency برای GraphQL
# graphql/context.py
from fastapi import Header
from utils.jwt import decode_access_token
from models.users import User
from config.database import SessionLocal
def get_current_user(authorization: str = Header(None)):
if not authorization:
raise Exception("Missing Authorization header")
token = authorization.replace("Bearer ", "")
payload = decode_access_token(token)
db = SessionLocal()
user = db.query(User).filter(User.id == payload.get("user_id")).first()
db.close()
if not user:
raise Exception("User not found")
return user
۴. استفاده از User در Resolver
# graphql/users.py
import strawberry
from graphql.context import get_current_user
@strawberry.type
class UserQuery:
@strawberry.field
def me(self, info) -> "UserType":
current_user = get_current_user(info.context["request"].headers.get("authorization"))
return UserType(
id=current_user.id,
email=current_user.email,
created_at=str(current_user.created_at),
updated_at=str(current_user.updated_at),
tasks=[]
)
۵. توضیح
- توکن JWT شامل اطلاعاتی مثل
user_id
است و به صورت امن امضا میشود. - در هر درخواست GraphQL، هدر
Authorization: Bearer <token>
بررسی میشود. - Resolverها با استفاده از توکن، کاربر را شناسایی و اجازه دسترسی میدهند.
- این روش مستقل از endpointهای GraphQL است و میتواند در همه Query و Mutationها اعمال شود.
در مراحل بعد میتوانیم این مکانیزم را با Custom Exception Handler و Middleware برای مدیریت یکپارچه احراز هویت ترکیب کنیم.