add cookie to auth

This commit is contained in:
cheykrym 2026-03-26 04:39:47 +03:00
parent 3fb959a2e9
commit 41cfb91d4e
2 changed files with 77 additions and 8 deletions

View File

@ -1,7 +1,7 @@
import httpx
from fastapi import Depends, Request, HTTPException, status, Header
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from typing import List
from typing import List, Optional
from dataclasses import dataclass
from config import settings
@ -23,11 +23,11 @@ class CurrentUser:
async def _fetch_current_user(
request: Request,
credentials: HTTPAuthorizationCredentials,
# credentials: HTTPAuthorizationCredentials,
token: str,
require_permissions: bool,
is_bot=False
) -> CurrentUser:
token = credentials.credentials
ip = request.client.host or "(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(
request: Request,
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
credentials: Optional[HTTPAuthorizationCredentials] = Depends(auth_scheme)
) -> 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(
request: Request,
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
) -> 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(
@ -155,8 +209,23 @@ async def get_current_user_or_bot(
is_bot: str | None = Header(default=None),
credentials: HTTPAuthorizationCredentials = Depends(auth_scheme)
) -> 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
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,

View File

@ -1,6 +1,6 @@
[project]
name = "common-lib"
version = "0.0.45"
version = "0.0.46"
description = "Библиотека общих компонентов для микросервисов yobble"
authors = [{ name = "cheykrym", email = "you@example.com" }]
license = "MIT"