feat: добавлены новые функции и схемы в модуль auth
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Lint project / lint (push) Successful in 1m41s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Lint project / lint (push) Successful in 1m41s
				
			- Добавлен класс UserVerifySchema для валидации данных пользователя, наследующий GetUserByID и GetUserByEmail. - Обновлена модель AuthUser для регистрации пользователя. - Добавлены роуты logout и get-user для работы с аутентификацией. - Создан новый модуль utils с функцией get_token_from_cookies для извлечения токена из куки. - Добавлена логика для выхода пользователя и получения информации об авторизованном пользователе в сервисах и роутах. - Обновлены схемы и зависимости в модуле handlers и managers для работы с аутентификацией.
This commit is contained in:
		
							
								
								
									
										52
									
								
								lkeep/apps/auth/depends.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								lkeep/apps/auth/depends.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					Проект: Lkeep
 | 
				
			||||||
 | 
					Автор: Иван Ашихмин
 | 
				
			||||||
 | 
					Год: 2025
 | 
				
			||||||
 | 
					Специально для проекта "Код на салфетке"
 | 
				
			||||||
 | 
					https://pressanybutton.ru/category/servis-na-fastapi/
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import uuid
 | 
				
			||||||
 | 
					from typing import Annotated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from fastapi import Depends, HTTPException
 | 
				
			||||||
 | 
					from starlette import status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from lkeep.apps.auth.handlers import AuthHandler
 | 
				
			||||||
 | 
					from lkeep.apps.auth.managers import UserManager
 | 
				
			||||||
 | 
					from lkeep.apps.auth.schemas import UserVerifySchema
 | 
				
			||||||
 | 
					from lkeep.apps.auth.utils import get_token_from_cookies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def get_current_user(
 | 
				
			||||||
 | 
					    token: Annotated[str, Depends(get_token_from_cookies)],
 | 
				
			||||||
 | 
					    handler: AuthHandler = Depends(AuthHandler),
 | 
				
			||||||
 | 
					    manager: UserManager = Depends(UserManager),
 | 
				
			||||||
 | 
					) -> UserVerifySchema:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Получает текущего пользователя из токена аутентификации.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param token: Токен аутентификации, полученный из куки.
 | 
				
			||||||
 | 
					    :type token: str
 | 
				
			||||||
 | 
					    :param handler: Обработчик аутентификации, использующийся для декодирования токена.
 | 
				
			||||||
 | 
					    :type handler: AuthHandler
 | 
				
			||||||
 | 
					    :param manager: Менеджер пользователей, используется для проверки и получения данных о пользователе.
 | 
				
			||||||
 | 
					    :type manager: UserManager
 | 
				
			||||||
 | 
					    :returns: Схема с информацией о текущем пользователе.
 | 
				
			||||||
 | 
					    :rtype: UserVerifySchema
 | 
				
			||||||
 | 
					    :raises HTTPException: Если токен невалиден или пользователь не найден.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    decoded_token = await handler.decode_access_token(token=token)
 | 
				
			||||||
 | 
					    user_id = str(decoded_token.get("user_id"))
 | 
				
			||||||
 | 
					    session_id = str(decoded_token.get("session_id"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if not await manager.get_access_token(user_id=user_id, session_id=session_id):
 | 
				
			||||||
 | 
					        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token is invalid")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user = await manager.get_user_by_id(user_id=uuid.UUID(user_id))
 | 
				
			||||||
 | 
					    if user is None:
 | 
				
			||||||
 | 
					        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user.session_id = session_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return user
 | 
				
			||||||
@@ -10,7 +10,9 @@ import datetime
 | 
				
			|||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import jwt
 | 
					import jwt
 | 
				
			||||||
 | 
					from fastapi import HTTPException
 | 
				
			||||||
from passlib.context import CryptContext
 | 
					from passlib.context import CryptContext
 | 
				
			||||||
 | 
					from starlette import status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lkeep.apps.auth.named_tuples import CreateTokenTuple
 | 
					from lkeep.apps.auth.named_tuples import CreateTokenTuple
 | 
				
			||||||
from lkeep.core.settings import settings
 | 
					from lkeep.core.settings import settings
 | 
				
			||||||
@@ -70,3 +72,22 @@ class AuthHandler:
 | 
				
			|||||||
        encoded_jwt = jwt.encode(payload=data, key=self.secret, algorithm="HS256")
 | 
					        encoded_jwt = jwt.encode(payload=data, key=self.secret, algorithm="HS256")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return CreateTokenTuple(encoded_jwt=encoded_jwt, session_id=session_id)
 | 
					        return CreateTokenTuple(encoded_jwt=encoded_jwt, session_id=session_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def decode_access_token(self, token: str) -> dict:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Декодирует JWT-токен и возвращает его содержимое.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param token: Строка с JWT-токеном, который нужно декодировать.
 | 
				
			||||||
 | 
					        :type token: str
 | 
				
			||||||
 | 
					        :returns: Данные, содержащиеся в декодированном токене.
 | 
				
			||||||
 | 
					        :rtype: dict
 | 
				
			||||||
 | 
					        :raises HTTPException: При ошибке декодирования токена (например, токен просрочен или невалиден).
 | 
				
			||||||
 | 
					                Статус-код ответа 401 UNAUTHORIZED, детализация "Token has expired" при просрочке,
 | 
				
			||||||
 | 
					                и "Invalid token" при недопустимости токена.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            return jwt.decode(jwt=token, key=self.secret, algorithms=["HS256"])
 | 
				
			||||||
 | 
					        except jwt.ExpiredSignatureError:
 | 
				
			||||||
 | 
					            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token has expired")
 | 
				
			||||||
 | 
					        except jwt.InvalidTokenError:
 | 
				
			||||||
 | 
					            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,12 @@ from fastapi import Depends, HTTPException
 | 
				
			|||||||
from sqlalchemy import insert, select, update
 | 
					from sqlalchemy import insert, select, update
 | 
				
			||||||
from sqlalchemy.exc import IntegrityError
 | 
					from sqlalchemy.exc import IntegrityError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lkeep.apps.auth.schemas import CreateUser, GetUserWithIDAndEmail, UserReturnData
 | 
					from lkeep.apps.auth.schemas import (
 | 
				
			||||||
 | 
					    CreateUser,
 | 
				
			||||||
 | 
					    GetUserWithIDAndEmail,
 | 
				
			||||||
 | 
					    UserReturnData,
 | 
				
			||||||
 | 
					    UserVerifySchema,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from lkeep.core.core_dependency.db_dependency import DBDependency
 | 
					from lkeep.core.core_dependency.db_dependency import DBDependency
 | 
				
			||||||
from lkeep.core.core_dependency.redis_dependency import RedisDependency
 | 
					from lkeep.core.core_dependency.redis_dependency import RedisDependency
 | 
				
			||||||
from lkeep.database.models import User
 | 
					from lkeep.database.models import User
 | 
				
			||||||
@@ -93,6 +98,27 @@ class UserManager:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def get_user_by_id(self, user_id: uuid.UUID | str) -> UserVerifySchema | None:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Возвращает информацию о пользователе по его идентификатору.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param user_id: Идентификатор пользователя, для которого нужно получить информацию.
 | 
				
			||||||
 | 
					            Может быть представлен в виде UUID или строки.
 | 
				
			||||||
 | 
					        :type user_id: uuid.UUID | str
 | 
				
			||||||
 | 
					        :returns: Схема данных пользователя, если пользователь найден; None, если пользователь не найден.
 | 
				
			||||||
 | 
					        :rtype: UserVerifySchema | None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        async with self.db.db_session() as session:
 | 
				
			||||||
 | 
					            query = select(self.model.id, self.model.email).where(self.model.id == user_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            result = await session.execute(query)
 | 
				
			||||||
 | 
					            user = result.mappings().one_or_none()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if user:
 | 
				
			||||||
 | 
					                return UserVerifySchema(**user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def store_access_token(self, token: str, user_id: uuid.UUID | str, session_id: str) -> None:
 | 
					    async def store_access_token(self, token: str, user_id: uuid.UUID | str, session_id: str) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Сохраняет токен доступа в хранилище (Redis).
 | 
					        Сохраняет токен доступа в хранилище (Redis).
 | 
				
			||||||
@@ -106,3 +132,30 @@ class UserManager:
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        async with self.redis.get_client() as client:
 | 
					        async with self.redis.get_client() as client:
 | 
				
			||||||
            await client.set(f"{user_id}:{session_id}", token)
 | 
					            await client.set(f"{user_id}:{session_id}", token)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def get_access_token(self, user_id: uuid.UUID | str, session_id: str) -> str | None:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Получает токен доступа из кэша по идентификаторам пользователя и сессии.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param user_id: Идентификатор пользователя, может быть в формате UUID или строка.
 | 
				
			||||||
 | 
					        :type user_id: uuid.UUID | str
 | 
				
			||||||
 | 
					        :param session_id: Идентификатор сессии, строка.
 | 
				
			||||||
 | 
					        :type session_id: str
 | 
				
			||||||
 | 
					        :returns: Токен доступа из кэша, если он существует; иначе None.
 | 
				
			||||||
 | 
					        :rtype: str | None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        async with self.redis.get_client() as client:
 | 
				
			||||||
 | 
					            return await client.get(f"{user_id}:{session_id}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def revoke_access_token(self, user_id: uuid.UUID | str, session_id: str | uuid.UUID | None) -> None:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Отзывает доступный токен доступа пользователя.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param user_id: Идентификатор пользователя, которому принадлежит токен.
 | 
				
			||||||
 | 
					        :type user_id: uuid.UUID | str
 | 
				
			||||||
 | 
					        :param session_id: Идентификатор сессии, для которой должен быть отозван токен.
 | 
				
			||||||
 | 
					            Если None, то все сессии пользователя будут отозваны.
 | 
				
			||||||
 | 
					        :type session_id: str | uuid.UUID | None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        async with self.redis.get_client() as client:
 | 
				
			||||||
 | 
					            await client.delete(f"{user_id}:{session_id}")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,11 +6,14 @@
 | 
				
			|||||||
https://pressanybutton.ru/category/servis-na-fastapi/
 | 
					https://pressanybutton.ru/category/servis-na-fastapi/
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from typing import Annotated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from fastapi import APIRouter, Depends
 | 
					from fastapi import APIRouter, Depends
 | 
				
			||||||
from starlette import status
 | 
					from starlette import status
 | 
				
			||||||
from starlette.responses import JSONResponse
 | 
					from starlette.responses import JSONResponse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lkeep.apps.auth.schemas import AuthUser, UserReturnData
 | 
					from lkeep.apps.auth.depends import get_current_user
 | 
				
			||||||
 | 
					from lkeep.apps.auth.schemas import AuthUser, UserReturnData, UserVerifySchema
 | 
				
			||||||
from lkeep.apps.auth.services import UserService
 | 
					from lkeep.apps.auth.services import UserService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auth_router = APIRouter(prefix="/auth", tags=["auth"])
 | 
					auth_router = APIRouter(prefix="/auth", tags=["auth"])
 | 
				
			||||||
@@ -63,3 +66,35 @@ async def login(user: AuthUser, service: UserService = Depends(UserService)) ->
 | 
				
			|||||||
    :raises HTTPException: Если учетные данные не верны или произошла другая ошибка при входе.
 | 
					    :raises HTTPException: Если учетные данные не верны или произошла другая ошибка при входе.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    return await service.login_user(user=user)
 | 
					    return await service.login_user(user=user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@auth_router.get(path="/logout", status_code=status.HTTP_200_OK)
 | 
				
			||||||
 | 
					async def logout(
 | 
				
			||||||
 | 
					    user: Annotated[UserVerifySchema, Depends(get_current_user)], service: UserService = Depends(UserService)
 | 
				
			||||||
 | 
					) -> JSONResponse:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Описание функции logout.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param user: Текущий авторизованный пользователь.
 | 
				
			||||||
 | 
					    :type user: UserVerifySchema
 | 
				
			||||||
 | 
					    :param service: Сервис для управления пользователями.
 | 
				
			||||||
 | 
					    :type service: UserService
 | 
				
			||||||
 | 
					    :returns: JSON-ответ, содержащий результат логаута.
 | 
				
			||||||
 | 
					    :rtype: JSONResponse
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    return await service.logout_user(user=user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@auth_router.get(path="/get-user", status_code=status.HTTP_200_OK, response_model=UserVerifySchema)
 | 
				
			||||||
 | 
					async def get_auth_user(user: Annotated[UserVerifySchema, Depends(get_current_user)]) -> UserVerifySchema:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Возвращает информацию об авторизованном пользователе.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param user: Информация о пользователе, полученная с помощью механизма аутентификации.
 | 
				
			||||||
 | 
					    :type user: UserVerifySchema
 | 
				
			||||||
 | 
					    :return: Схема данных пользователя, содержащая необходимую информацию для работы системы.
 | 
				
			||||||
 | 
					    :rtype: UserVerifySchema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :raises HTTPException 401: Если пользователь не авторизован и попытка получить доступ к защищенному ресурсу.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    return user
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,17 @@ class GetUserByEmail(BaseModel):
 | 
				
			|||||||
    email: EmailStr
 | 
					    email: EmailStr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserVerifySchema(GetUserByID, GetUserByEmail):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Класс для валидации данных пользователя.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Данный класс наследует методы из классов GetUserByID и GetUserByEmail,
 | 
				
			||||||
 | 
					    что позволяет использовать их функциональность для проверки данных пользователя.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    session_id: uuid.UUID | str | None = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AuthUser(GetUserByEmail):
 | 
					class AuthUser(GetUserByEmail):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Класс для регистрации пользователя, наследующий класс GetUserByEmail.
 | 
					    Класс для регистрации пользователя, наследующий класс GetUserByEmail.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,12 @@ from starlette.responses import JSONResponse
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from lkeep.apps.auth.handlers import AuthHandler
 | 
					from lkeep.apps.auth.handlers import AuthHandler
 | 
				
			||||||
from lkeep.apps.auth.managers import UserManager
 | 
					from lkeep.apps.auth.managers import UserManager
 | 
				
			||||||
from lkeep.apps.auth.schemas import AuthUser, CreateUser, UserReturnData
 | 
					from lkeep.apps.auth.schemas import (
 | 
				
			||||||
 | 
					    AuthUser,
 | 
				
			||||||
 | 
					    CreateUser,
 | 
				
			||||||
 | 
					    UserReturnData,
 | 
				
			||||||
 | 
					    UserVerifySchema,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from lkeep.apps.auth.tasks import send_confirmation_email
 | 
					from lkeep.apps.auth.tasks import send_confirmation_email
 | 
				
			||||||
from lkeep.core.settings import settings
 | 
					from lkeep.core.settings import settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -85,7 +90,7 @@ class UserService:
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        exist_user = await self.manager.get_user_by_email(email=user.email)
 | 
					        exist_user = await self.manager.get_user_by_email(email=user.email)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if exist_user is None or not self.handler.verify_password(
 | 
					        if exist_user is None or not await self.handler.verify_password(
 | 
				
			||||||
            hashed_password=exist_user.hashed_password, raw_password=user.password
 | 
					            hashed_password=exist_user.hashed_password, raw_password=user.password
 | 
				
			||||||
        ):
 | 
					        ):
 | 
				
			||||||
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Wrong email or password")
 | 
					            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Wrong email or password")
 | 
				
			||||||
@@ -103,3 +108,20 @@ class UserService:
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response
 | 
					        return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def logout_user(self, user: UserVerifySchema) -> JSONResponse:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Отправляет запрос на выход пользователя из системы.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param user: Схема, содержащая информацию о пользователе для аутентификации.
 | 
				
			||||||
 | 
					        :type user: UserVerifySchema
 | 
				
			||||||
 | 
					        :returns: Ответ сервера с сообщением об успешном выходе пользователя.
 | 
				
			||||||
 | 
					        :rtype: JSONResponse
 | 
				
			||||||
 | 
					        :raises Exception: Если произошла ошибка при отмене токена доступа.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        await self.manager.revoke_access_token(user_id=user.id, session_id=user.session_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        response = JSONResponse(content={"message": "Logged out"})
 | 
				
			||||||
 | 
					        response.delete_cookie(key="Authorization")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								lkeep/apps/auth/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								lkeep/apps/auth/utils.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					Проект: Lkeep
 | 
				
			||||||
 | 
					Автор: Иван Ашихмин
 | 
				
			||||||
 | 
					Год: 2025
 | 
				
			||||||
 | 
					Специально для проекта "Код на салфетке"
 | 
				
			||||||
 | 
					https://pressanybutton.ru/category/servis-na-fastapi/
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from fastapi import HTTPException
 | 
				
			||||||
 | 
					from starlette import status
 | 
				
			||||||
 | 
					from starlette.requests import Request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def get_token_from_cookies(request: Request) -> str:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Получает токен из куки запроса.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param request: Объект HTTP-запроса.
 | 
				
			||||||
 | 
					    :type request: Request
 | 
				
			||||||
 | 
					    :return: Токен из cookies.
 | 
				
			||||||
 | 
					    :rtype: str
 | 
				
			||||||
 | 
					    :raises HTTPException: Если в запросе отсутствует cookie с ключом "Authorization".
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    token = request.cookies.get("Authorization")
 | 
				
			||||||
 | 
					    if token is None:
 | 
				
			||||||
 | 
					        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token is missing")
 | 
				
			||||||
 | 
					    return token
 | 
				
			||||||
							
								
								
									
										0
									
								
								tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user