add cookie to auth
This commit is contained in:
parent
3fb959a2e9
commit
41cfb91d4e
@ -1,7 +1,7 @@
|
|||||||
import httpx
|
import httpx
|
||||||
from fastapi import Depends, Request, HTTPException, status, Header
|
from fastapi import Depends, Request, HTTPException, status, Header
|
||||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from config import settings
|
from config import settings
|
||||||
@ -23,11 +23,11 @@ class CurrentUser:
|
|||||||
|
|
||||||
async def _fetch_current_user(
|
async def _fetch_current_user(
|
||||||
request: Request,
|
request: Request,
|
||||||
credentials: HTTPAuthorizationCredentials,
|
# credentials: HTTPAuthorizationCredentials,
|
||||||
|
token: str,
|
||||||
require_permissions: bool,
|
require_permissions: bool,
|
||||||
is_bot=False
|
is_bot=False
|
||||||
) -> CurrentUser:
|
) -> CurrentUser:
|
||||||
token = credentials.credentials
|
|
||||||
ip = request.client.host or "(unknown)"
|
ip = request.client.host or "(unknown)"
|
||||||
user_agent = request.headers.get("User-Agent", "(unknown)")
|
user_agent = request.headers.get("User-Agent", "(unknown)")
|
||||||
|
|
||||||
@ -136,18 +136,72 @@ async def fetch_user_for_sio(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_token_from_request(request: Request) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Пытается извлечь access token:
|
||||||
|
1. Сначала из заголовка Authorization: Bearer <token>
|
||||||
|
2. Если нет — из куки yobble_access_token
|
||||||
|
3. Если нигде нет — возвращает None
|
||||||
|
"""
|
||||||
|
# 1. Пробуем заголовок
|
||||||
|
auth_header = request.headers.get("Authorization")
|
||||||
|
if auth_header and auth_header.startswith("Bearer "):
|
||||||
|
token = auth_header[7:].strip() # Убираем "Bearer "
|
||||||
|
if token: # Не пустой
|
||||||
|
return token
|
||||||
|
|
||||||
|
# 2. Пробуем куку (если httponly=False, фронт мог не подставить в заголовок)
|
||||||
|
cookie_token = request.cookies.get("yobble_access_token")
|
||||||
|
if cookie_token and cookie_token != "none":
|
||||||
|
return cookie_token
|
||||||
|
|
||||||
|
# 3. Ничего не найдено
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_current_user(
|
async def get_current_user(
|
||||||
request: Request,
|
request: Request,
|
||||||
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
|
credentials: Optional[HTTPAuthorizationCredentials] = Depends(auth_scheme)
|
||||||
) -> CurrentUser:
|
) -> CurrentUser:
|
||||||
return await _fetch_current_user(request, credentials, require_permissions=False)
|
token = None
|
||||||
|
|
||||||
|
if credentials and credentials.credentials:
|
||||||
|
token = credentials.credentials
|
||||||
|
is_web = False
|
||||||
|
else:
|
||||||
|
token = _extract_token_from_request(request)
|
||||||
|
is_web = True
|
||||||
|
|
||||||
|
if not token:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Authentication required: provide token in Authorization header or cookie"
|
||||||
|
)
|
||||||
|
|
||||||
|
return await _fetch_current_user(request, token, require_permissions=False, is_web=is_web)
|
||||||
|
|
||||||
|
|
||||||
async def get_current_user_with_permissions(
|
async def get_current_user_with_permissions(
|
||||||
request: Request,
|
request: Request,
|
||||||
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
|
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
|
||||||
) -> CurrentUser:
|
) -> CurrentUser:
|
||||||
return await _fetch_current_user(request, credentials, require_permissions=True)
|
token = None
|
||||||
|
|
||||||
|
if credentials and credentials.credentials:
|
||||||
|
token = credentials.credentials
|
||||||
|
is_web = False
|
||||||
|
else:
|
||||||
|
token = _extract_token_from_request(request)
|
||||||
|
is_web = True
|
||||||
|
|
||||||
|
if not token:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Authentication required: provide token in Authorization header or cookie"
|
||||||
|
)
|
||||||
|
|
||||||
|
return await _fetch_current_user(request, token, require_permissions=True)
|
||||||
|
|
||||||
|
|
||||||
async def get_current_user_or_bot(
|
async def get_current_user_or_bot(
|
||||||
@ -155,8 +209,23 @@ async def get_current_user_or_bot(
|
|||||||
is_bot: str | None = Header(default=None),
|
is_bot: str | None = Header(default=None),
|
||||||
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
|
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
|
||||||
) -> CurrentUser:
|
) -> CurrentUser:
|
||||||
|
token = None
|
||||||
|
|
||||||
|
if credentials and credentials.credentials:
|
||||||
|
token = credentials.credentials
|
||||||
|
is_web = False
|
||||||
|
else:
|
||||||
|
token = _extract_token_from_request(request)
|
||||||
|
is_web = True
|
||||||
|
|
||||||
|
if not token:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Authentication required: provide token in Authorization header or cookie"
|
||||||
|
)
|
||||||
|
|
||||||
is_bot_flag = str(is_bot).lower() in ("true", "1", "yes") if is_bot else False
|
is_bot_flag = str(is_bot).lower() in ("true", "1", "yes") if is_bot else False
|
||||||
return await _fetch_current_user(request, credentials, require_permissions=False, is_bot=is_bot_flag)
|
return await _fetch_current_user(request, token, require_permissions=False, is_bot=is_bot_flag)
|
||||||
|
|
||||||
|
|
||||||
def validate_username(value: str,
|
def validate_username(value: str,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "common-lib"
|
name = "common-lib"
|
||||||
version = "0.0.45"
|
version = "0.0.46"
|
||||||
description = "Библиотека общих компонентов для микросервисов yobble"
|
description = "Библиотека общих компонентов для микросервисов yobble"
|
||||||
authors = [{ name = "cheykrym", email = "you@example.com" }]
|
authors = [{ name = "cheykrym", email = "you@example.com" }]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user