diff --git a/backend/requirements.txt b/backend/requirements.txt index 320f59f..7fe8d81 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -4,4 +4,5 @@ sqlalchemy passlib[bcrypt] pydantic starlette -python-multipart \ No newline at end of file +python-multipart +python-jose[cryptography] \ No newline at end of file diff --git a/backend/routers/auth.py b/backend/routers/auth.py index eec56ee..a5f1081 100644 --- a/backend/routers/auth.py +++ b/backend/routers/auth.py @@ -1,3 +1,4 @@ +from datetime import timedelta, datetime from typing import Annotated from fastapi import APIRouter, Depends from pydantic import BaseModel @@ -5,12 +6,16 @@ from passlib.context import CryptContext from sqlalchemy.orm import Session from starlette import status from fastapi.security import OAuth2PasswordRequestForm +from jose import jwt from models import User from database import SessionLocal router = APIRouter() +SECRET_KEY = '3b004eeae34b43bd05226f210d9bdc2ad99abdd3c52bf32802906085b762ff55' +ALGORITHM = 'HS256' + bcrypt_context = CryptContext(schemes=['bcrypt'], deprecated='auto') @@ -31,7 +36,15 @@ def authenticate_user(username: str, password: str, db): return False if not bcrypt_context.verify(password, user.password): return False - return True + return user + + +def create_access_token(username: str, user_id: int, expires_delta: timedelta): + encode = {'sub': username, 'id': user_id} + expire = datetime.now() + expires_delta + encode.update({'exp': expire}) + + return jwt.encode(encode, SECRET_KEY, ALGORITHM) class CreateUser(BaseModel): @@ -40,6 +53,11 @@ class CreateUser(BaseModel): password: str +class Token(BaseModel): + access_token: str + token_type: str + + @router.post('/auth/create', status_code=status.HTTP_201_CREATED) async def create_user(db: db_dependency, data: CreateUser): create_user_model = User( @@ -53,13 +71,14 @@ async def create_user(db: db_dependency, data: CreateUser): db.commit() -@router.post('/auth/token', status_code=status.HTTP_200_OK) +@router.post('/auth/token', status_code=status.HTTP_200_OK, response_model=Token) async def get_token( form_data: Annotated[OAuth2PasswordRequestForm, Depends()], db: db_dependency ): user = authenticate_user(form_data.username, form_data.password, db) - if user: - return "you good fam" + if not user: + return "authentication failed" - return "failed authentication" + token = create_access_token(user.username, user.id, timedelta(minutes=20)) + return {'access_token': token, 'token_type': 'bearer'}