controller.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. # -*- coding: utf-8 -*-
  2. from typing import Union, Dict
  3. from fastapi import APIRouter, Depends, Request
  4. from fastapi.responses import JSONResponse
  5. from sqlalchemy.ext.asyncio import AsyncSession
  6. from redis.asyncio.client import Redis
  7. from app.common.response import ErrorResponse, SuccessResponse
  8. from app.core.router_class import OperationLogRoute
  9. from app.core.security import CustomOAuth2PasswordRequestForm
  10. from app.core.logger import log
  11. from app.config.setting import settings
  12. from app.core.dependencies import (
  13. db_getter,
  14. get_current_user,
  15. redis_getter
  16. )
  17. from .service import (
  18. LoginService,
  19. CaptchaService
  20. )
  21. from .schema import (
  22. CaptchaOutSchema,
  23. JWTOutSchema,
  24. RefreshTokenPayloadSchema,
  25. LogoutPayloadSchema
  26. )
  27. AuthRouter = APIRouter(route_class=OperationLogRoute, prefix="/auth", tags=["认证授权"])
  28. @AuthRouter.post("/login", summary="登录", description="登录", response_model=JWTOutSchema)
  29. async def login_for_access_token_controller(
  30. request: Request,
  31. redis: Redis = Depends(redis_getter),
  32. login_form: CustomOAuth2PasswordRequestForm = Depends(),
  33. db: AsyncSession = Depends(db_getter),
  34. ) -> Union[JSONResponse, Dict]:
  35. """
  36. 用户登录
  37. 参数:
  38. - request (Request): FastAPI请求对象
  39. - login_form (CustomOAuth2PasswordRequestForm): 登录表单数据
  40. - db (AsyncSession): 数据库会话对象
  41. 返回:
  42. - JWTOutSchema: 包含访问令牌和刷新令牌的响应模型
  43. 异常:
  44. - CustomException: 认证失败时抛出异常。
  45. """
  46. login_token = await LoginService.authenticate_user_service(request=request, redis=redis, login_form=login_form, db=db)
  47. log.info(f"用户{login_form.username}登录成功")
  48. # 如果是文档请求,则不记录日志:http://localhost:8000/api/v1/docs
  49. if settings.DOCS_URL in request.headers.get("referer", ""):
  50. return login_token.model_dump()
  51. return SuccessResponse(data=login_token.model_dump(), msg="登录成功")
  52. @AuthRouter.post("/token/refresh", summary="刷新token", description="刷新token", response_model=JWTOutSchema, dependencies=[Depends(get_current_user)])
  53. async def get_new_token_controller(
  54. request: Request,
  55. payload: RefreshTokenPayloadSchema,
  56. db: AsyncSession = Depends(db_getter),
  57. redis: Redis = Depends(redis_getter)
  58. ) -> JSONResponse:
  59. """
  60. 刷新token
  61. 参数:
  62. - request (Request): FastAPI请求对象
  63. - payload (RefreshTokenPayloadSchema): 刷新令牌负载模型
  64. 返回:
  65. - JWTOutSchema: 包含新的访问令牌和刷新令牌的响应模型
  66. 异常:
  67. - CustomException: 刷新令牌失败时抛出异常。
  68. """
  69. # 解析当前的访问Token以获取用户名
  70. new_token = await LoginService.refresh_token_service(db=db, request=request, redis=redis, refresh_token=payload)
  71. token_dict = new_token.model_dump()
  72. log.info(f"刷新token成功: {token_dict}")
  73. return SuccessResponse(data=token_dict, msg="刷新成功")
  74. @AuthRouter.get("/captcha/get", summary="获取验证码", description="获取登录验证码", response_model=CaptchaOutSchema)
  75. async def get_captcha_for_login_controller(
  76. redis: Redis = Depends(redis_getter)
  77. ) -> JSONResponse:
  78. """
  79. 获取登录验证码
  80. 参数:
  81. - redis (Redis): Redis客户端对象
  82. 返回:
  83. - CaptchaOutSchema: 包含验证码图片和key的响应模型
  84. 异常:
  85. - CustomException: 获取验证码失败时抛出异常。
  86. """
  87. # 获取验证码
  88. captcha = await CaptchaService.get_captcha_service(redis=redis)
  89. log.info(f"获取验证码成功")
  90. return SuccessResponse(data=captcha, msg="获取验证码成功")
  91. @AuthRouter.post('/logout', summary="退出登录", description="退出登录", dependencies=[Depends(get_current_user)])
  92. async def logout_controller(
  93. payload: LogoutPayloadSchema,
  94. redis: Redis = Depends(redis_getter)
  95. ) -> JSONResponse:
  96. """
  97. 退出登录
  98. 参数:
  99. - payload (LogoutPayloadSchema): 退出登录负载模型
  100. - redis (Redis): Redis客户端对象
  101. 返回:
  102. - JSONResponse: 包含退出登录结果的响应模型
  103. 异常:
  104. - CustomException: 退出登录失败时抛出异常。
  105. """
  106. if await LoginService.logout_service(redis=redis, token=payload):
  107. log.info('退出成功')
  108. return SuccessResponse(msg='退出成功')
  109. return ErrorResponse(msg='退出失败')