Browse Source

Added token expiration

main
Madiwka3 1 year ago
parent
commit
4cac217ce4
6 changed files with 68 additions and 27 deletions
  1. +49
    -16
      app/apis/v1/route_auth.py
  2. +1
    -1
      app/apis/v1/route_vehicle.py
  3. +3
    -2
      app/core/auth.py
  4. +6
    -7
      app/core/config.py
  5. +4
    -1
      app/main.py
  6. +5
    -0
      app/schemas/token.py

+ 49
- 16
app/apis/v1/route_auth.py View File

@@ -1,3 +1,4 @@
from datetime import datetime
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from fastapi import Depends, APIRouter from fastapi import Depends, APIRouter
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -7,20 +8,23 @@ from db.session import get_db
from core.hashing import Hasher from core.hashing import Hasher
from core.config import settings from core.config import settings
from jose import JWTError, jwt from jose import JWTError, jwt
from schemas.token import Token
from schemas.token import Token, TokenPayload
from db.repository.user import get_user_by_email, get_user_by_phone from db.repository.user import get_user_by_email, get_user_by_phone
from core.auth import create_access_token from core.auth import create_access_token



router = APIRouter() router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")
oauth2_scheme = OAuth2PasswordBearer(
tokenUrl="/token",
)




def authenticate_user(login: str, password: str, db: Session): def authenticate_user(login: str, password: str, db: Session):
print("Trying to auth...") print("Trying to auth...")
user = None user = None
if ("@" in login):
if "@" in login:
user = get_user_by_email(email=login, db=db) user = get_user_by_email(email=login, db=db)
elif ("+" in login):
elif "+" in login:
user = get_user_by_phone(phone=login, db=db) user = get_user_by_phone(phone=login, db=db)
else: else:
return False return False
@@ -31,32 +35,61 @@ def authenticate_user(login: str, password: str, db: Session):
return user return user




def get_current_user(token: Annotated[str, Depends(oauth2_scheme)], db: Annotated[Session, Depends(get_db)]):
def get_current_user(
token: Annotated[str, Depends(oauth2_scheme)],
db: Annotated[Session, Depends(get_db)],
):
print("Getting current user...") print("Getting current user...")
try: try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
payload = jwt.decode(
token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]
)
token_data = TokenPayload(**payload)

if datetime.fromtimestamp(token_data.exp) < datetime.now():
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Session expired. Please login again.",
)
username: str = payload.get("sub") username: str = payload.get("sub")
if username is None: if username is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
except JWTError: except JWTError:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
if ("@" in username):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
if "@" in username:
user = get_user_by_email(email=username, db=db) user = get_user_by_email(email=username, db=db)
elif ("+" in username):
elif "+" in username:
user = get_user_by_phone(phone=username, db=db) user = get_user_by_phone(phone=username, db=db)
else: else:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
return user return user




@router.post("/token", response_model=Token) @router.post("/token", response_model=Token)
def access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
def access_token(
form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)
):
print("Getting token...") print("Getting token...")
user = authenticate_user(form_data.username, form_data.password, db) user = authenticate_user(form_data.username, form_data.password, db)
print(user) print(user)
if not user: if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid username or password")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid username or password",
)
access_token = create_access_token(data={"sub": user.Email}) access_token = create_access_token(data={"sub": user.Email})
return {"access_token": access_token, "token_type": "bearer"}


print("TOKENS ARE: ")
print(access_token)
return {
"access_token": access_token,
"token_type": "bearer",
}

+ 1
- 1
app/apis/v1/route_vehicle.py View File

@@ -1,7 +1,7 @@
from fastapi import APIRouter, status, HTTPException from fastapi import APIRouter, status, HTTPException
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from fastapi import Depends from fastapi import Depends
from typing import Annotated, List
from typing import List
from db.session import get_db from db.session import get_db
from schemas.vehicle import OutputVehicle, CreateVehicle, UpdateVehicle, VehicleLocation from schemas.vehicle import OutputVehicle, CreateVehicle, UpdateVehicle, VehicleLocation
from db.repository.vehicle import ( from db.repository.vehicle import (


+ 3
- 2
app/core/auth.py View File

@@ -12,6 +12,7 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
else: else:
expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE) expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE)
to_encode.update({"exp": expire}) to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
encoded_jwt = jwt.encode(
to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM
)
return encoded_jwt return encoded_jwt


+ 6
- 7
app/core/config.py View File

@@ -1,5 +1,3 @@


class Settings: class Settings:
PROJECT_NAME: str = "VMS" PROJECT_NAME: str = "VMS"
PROJECT_VERSION: str = "1.0.0" PROJECT_VERSION: str = "1.0.0"
@@ -9,7 +7,7 @@ class Settings:
POSTGRES_PORT: str = "5432" POSTGRES_PORT: str = "5432"
POSTGRES_DB: str = "VMSData" POSTGRES_DB: str = "VMSData"
DATABASE_URL = f"postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_SERVER}:{POSTGRES_PORT}/{POSTGRES_DB}" DATABASE_URL = f"postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_SERVER}:{POSTGRES_PORT}/{POSTGRES_DB}"
ACCESS_TOKEN_EXPIRE: int = 30
ACCESS_TOKEN_EXPIRE: int = 60 * 24 * 7 # 7 days
SECRET_KEY: str = "tH357aC6oA7ofCaN3yTffYkRh" SECRET_KEY: str = "tH357aC6oA7ofCaN3yTffYkRh"
ALGORITHM: str = "HS256" ALGORITHM: str = "HS256"


@@ -21,8 +19,8 @@ def createAdminAcc():
from db.session import SessionLocal from db.session import SessionLocal
from db.repository.user import create_new_user from db.repository.user import create_new_user
from schemas.user import UserCreate from schemas.user import UserCreate
from core.hashing import Hasher
from db.models.user import User from db.models.user import User

db = SessionLocal() db = SessionLocal()
user = UserCreate( user = UserCreate(
Email="madi.turgunov@nu.edu.kz", Email="madi.turgunov@nu.edu.kz",
@@ -31,8 +29,9 @@ def createAdminAcc():
LastName="Turgunov", LastName="Turgunov",
ContactNumber="+77071234567", ContactNumber="+77071234567",
Role="Admin", Role="Admin",
BirthDate="2000-01-01T00:00:00+06:00")
if (db.query(User).filter(User.Email == user.Email).first()):
BirthDate="2000-01-01T00:00:00+06:00",
)
if db.query(User).filter(User.Email == user.Email).first():
return False return False
create_new_user(user=user, db=db) create_new_user(user=user, db=db)
return True
return True

+ 4
- 1
app/main.py View File

@@ -10,7 +10,10 @@ def include_routes(app): # include all routes from our api/v1/




def startup(): # start the project, and create the tables def startup(): # start the project, and create the tables
app = FastAPI(title=settings.PROJECT_NAME, version=settings.PROJECT_VERSION)
app = FastAPI(
title=settings.PROJECT_NAME,
version=settings.PROJECT_VERSION,
)
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
createAdminAcc() createAdminAcc()
include_routes(app) include_routes(app)


+ 5
- 0
app/schemas/token.py View File

@@ -4,3 +4,8 @@ from pydantic import BaseModel
class Token(BaseModel): class Token(BaseModel):
access_token: str access_token: str
token_type: str token_type: str


class TokenPayload(BaseModel):
sub: str = None
exp: int = None

Loading…
Cancel
Save