ساخت Endpointهای احراز هویت (Signup و Login) برای GraphQL در FastAPI
در این بخش، دو Mutation اصلی برای ثبتنام و ورود کاربر ایجاد میکنیم. پس از ورود موفق، کاربر یک JWT دریافت میکند که برای دسترسی به سایر Query و Mutationها استفاده خواهد شد.
# graphql/users.py
import strawberry
from sqlalchemy.orm import Session
from models.users import User as UserModel
from graphql.types import UserType
from utils.jwt import create_access_token
from passlib.hash import bcrypt
from config.database import SessionLocal
@strawberry.type
class UserMutation:
@strawberry.mutation
def signup(self, info, email: str, password: str) -> UserType:
db: Session = SessionLocal()
try:
existing_user = db.query(UserModel).filter(UserModel.email == email).first()
if existing_user:
raise Exception("User with this email already exists")
hashed_password = bcrypt.hash(password)
new_user = UserModel(email=email, password=hashed_password)
db.add(new_user)
db.commit()
db.refresh(new_user)
return UserType(
id=new_user.id,
email=new_user.email,
created_at=str(new_user.created_at),
updated_at=str(new_user.updated_at),
tasks=[]
)
finally:
db.close()
@strawberry.mutation
def login(self, info, email: str, password: str) -> str:
db: Session = SessionLocal()
try:
user = db.query(UserModel).filter(UserModel.email == email).first()
if not user:
raise Exception("Invalid credentials")
if not bcrypt.verify(password, user.password):
raise Exception("Invalid credentials")
token = create_access_token({"user_id": user.id})
return token
finally:
db.close()
توضیح
- Signup: ابتدا بررسی میکند که کاربری با ایمیل داده شده وجود نداشته باشد، سپس رمز عبور را هش میکند و کاربر را در دیتابیس ذخیره میکند.
- Login: کاربر با ایمیل و رمز عبور بررسی میشود و در صورت موفقیت، توکن JWT ایجاد و بازگردانده میشود.
- JWT تولید شده میتواند در هدر
Authorization
برای دسترسی به سایر Query و Mutationها استفاده شود. - هر دو Mutation از Session دیتابیس استفاده میکنند و در نهایت آن را میبندند تا منابع آزاد شوند.
در مراحل بعد میتوانیم Queryهایی بسازیم که دسترسی آنها نیازمند احراز هویت JWT باشد و همچنین مدیریت خطاها را بهبود دهیم.