Fix token expiration

This commit is contained in:
2025-11-26 16:41:38 +03:00
Unverified
parent 3549f98691
commit dcad5dbbc2
3 changed files with 23 additions and 7 deletions
+4 -2
View File
@@ -1,9 +1,11 @@
import os import os
DATABASE_URL = "sqlite:///./data/database.db" DATABASE_URL = "sqlite:///./data/database.db"
JWT_ALGORITHM = "HS256" JWT_ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_HOURS = 24 # Token inactivity expiration - token expires if not used for this duration
TOKEN_INACTIVITY_EXPIRE_HOURS = 30 * 24 # 30 days of inactivity
# Maximum token lifetime (safety net) - tokens expire after this regardless of usage
MAX_TOKEN_LIFETIME_HOURS = 365 * 24 # 1 year maximum
OWNER_USERNAME = "denis0001-dev" OWNER_USERNAME = "denis0001-dev"
JWT_SECRET_KEY = os.getenv("JWT_SECRET") JWT_SECRET_KEY = os.getenv("JWT_SECRET")
+15 -2
View File
@@ -1,4 +1,4 @@
from datetime import datetime from datetime import datetime, timedelta
from fastapi import Depends, HTTPException, Request, status from fastapi import Depends, HTTPException, Request, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -66,7 +66,20 @@ def get_current_user(
headers={"WWW-Authenticate": "Bearer"}, headers={"WWW-Authenticate": "Bearer"},
) )
# Touch last_seen on valid session # Check if session has been inactive for too long (sliding expiration)
from constants import TOKEN_INACTIVITY_EXPIRE_HOURS
inactivity_threshold = datetime.now() - timedelta(hours=TOKEN_INACTIVITY_EXPIRE_HOURS)
if device_session.last_seen < inactivity_threshold:
# Session expired due to inactivity - revoke it
device_session.revoked = True
db.commit()
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Session expired due to inactivity",
headers={"WWW-Authenticate": "Bearer"},
)
# Touch last_seen on valid session (sliding expiration - extends token life)
device_session.last_seen = datetime.now() device_session.last_seen = datetime.now()
db.commit() db.commit()
+4 -3
View File
@@ -4,16 +4,17 @@ import jwt
from typing import Optional, Any from typing import Optional, Any
import bcrypt import bcrypt
from constants import ACCESS_TOKEN_EXPIRE_HOURS, JWT_SECRET_KEY, JWT_ALGORITHM from constants import MAX_TOKEN_LIFETIME_HOURS, JWT_SECRET_KEY, JWT_ALGORITHM
# JWT Helper Functions # JWT Helper Functions
def create_token(user_id: int, username: str, session_id: str) -> str: def create_token(user_id: int, username: str, session_id: str) -> str:
expire = datetime.now() + timedelta(hours=ACCESS_TOKEN_EXPIRE_HOURS) # Set a long expiration as safety net (actual expiration based on inactivity)
expire = datetime.now() + timedelta(hours=MAX_TOKEN_LIFETIME_HOURS)
payload = { payload = {
"user_id": user_id, "user_id": user_id,
"username": username, "username": username,
"session_id": session_id, "session_id": session_id,
"exp": expire "exp": int(expire.timestamp()) # JWT exp must be Unix timestamp (int)
} }
return jwt.encode(payload, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM) return jwt.encode(payload, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM)