Spaces:
Sleeping
Sleeping
Update core/security.py
Browse files- core/security.py +26 -39
core/security.py
CHANGED
|
@@ -1,36 +1,31 @@
|
|
| 1 |
from datetime import datetime, timedelta
|
| 2 |
-
from
|
|
|
|
| 3 |
from jose import jwt, JWTError
|
| 4 |
-
from fastapi import Depends, HTTPException, status, Request
|
| 5 |
-
from fastapi.security import OAuth2PasswordBearer
|
| 6 |
-
from core.config import SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES
|
| 7 |
-
from db.mongo import users_collection
|
| 8 |
import logging
|
| 9 |
|
| 10 |
logger = logging.getLogger(__name__)
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
)
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)):
|
| 34 |
credentials_exception = HTTPException(
|
| 35 |
status_code=status.HTTP_401_UNAUTHORIZED,
|
| 36 |
detail="Could not validate credentials",
|
|
@@ -38,26 +33,18 @@ async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)
|
|
| 38 |
)
|
| 39 |
|
| 40 |
try:
|
| 41 |
-
#
|
| 42 |
-
if not token:
|
| 43 |
-
# Fallback to checking cookies if using session-based auth
|
| 44 |
-
token = request.cookies.get("access_token")
|
| 45 |
-
if not token:
|
| 46 |
-
logger.error("No token provided in headers or cookies")
|
| 47 |
-
raise credentials_exception
|
| 48 |
-
|
| 49 |
-
# Remove 'Bearer ' prefix if present
|
| 50 |
if token.startswith("Bearer "):
|
| 51 |
token = token[7:]
|
| 52 |
-
|
| 53 |
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
| 54 |
email: str = payload.get("sub")
|
| 55 |
if email is None:
|
| 56 |
-
logger.error("Token missing 'sub' claim")
|
| 57 |
raise credentials_exception
|
| 58 |
|
| 59 |
except JWTError as e:
|
| 60 |
-
logger.error(f"JWT validation
|
| 61 |
raise credentials_exception
|
| 62 |
|
| 63 |
user = await users_collection.find_one({"email": email})
|
|
|
|
| 1 |
from datetime import datetime, timedelta
|
| 2 |
+
from fastapi import HTTPException, status, Request
|
| 3 |
+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
| 4 |
from jose import jwt, JWTError
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
import logging
|
| 6 |
|
| 7 |
logger = logging.getLogger(__name__)
|
| 8 |
|
| 9 |
+
class JWTBearer(HTTPBearer):
|
| 10 |
+
def __init__(self, auto_error: bool = True):
|
| 11 |
+
super().__init__(auto_error=auto_error)
|
| 12 |
+
|
| 13 |
+
async def __call__(self, request: Request):
|
| 14 |
+
credentials: HTTPAuthorizationCredentials = await super().__call__(request)
|
| 15 |
+
if credentials:
|
| 16 |
+
if not credentials.scheme == "Bearer":
|
| 17 |
+
raise HTTPException(
|
| 18 |
+
status_code=status.HTTP_403_FORBIDDEN,
|
| 19 |
+
detail="Invalid authentication scheme"
|
| 20 |
+
)
|
| 21 |
+
return credentials.credentials
|
| 22 |
+
else:
|
| 23 |
+
raise HTTPException(
|
| 24 |
+
status_code=status.HTTP_403_FORBIDDEN,
|
| 25 |
+
detail="Invalid authorization code"
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
async def get_current_user(request: Request, token: str = Depends(JWTBearer())):
|
|
|
|
|
|
|
| 29 |
credentials_exception = HTTPException(
|
| 30 |
status_code=status.HTTP_401_UNAUTHORIZED,
|
| 31 |
detail="Could not validate credentials",
|
|
|
|
| 33 |
)
|
| 34 |
|
| 35 |
try:
|
| 36 |
+
# Remove 'Bearer ' prefix if present (double-check)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
if token.startswith("Bearer "):
|
| 38 |
token = token[7:]
|
| 39 |
+
|
| 40 |
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
| 41 |
email: str = payload.get("sub")
|
| 42 |
if email is None:
|
| 43 |
+
logger.error("Token missing email in 'sub' claim")
|
| 44 |
raise credentials_exception
|
| 45 |
|
| 46 |
except JWTError as e:
|
| 47 |
+
logger.error(f"JWT validation failed: {str(e)}")
|
| 48 |
raise credentials_exception
|
| 49 |
|
| 50 |
user = await users_collection.find_one({"email": email})
|