diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ddac70 --- /dev/null +++ b/.gitignore @@ -0,0 +1,68 @@ +# Python 字节码文件 +__pycache__/ +*.py[cod] +*$py.class + +# C 扩展 +*.so + +# 分发/打包 +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# 虚拟环境 +venv/ +env/ +ENV/ +.env +.venv + +# 测试 +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Django 相关 +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +media/ + +# PyCharm IDE +.idea/ +*.iml +*.iws +*.ipr + +# VS Code +.vscode/ +*.code-workspace +.history/ + +# 其他 +.DS_Store + +logs/ +packages/ \ No newline at end of file diff --git a/api/__init__.py b/api/__init__.py index 30db9b3..70bac50 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -1,6 +1,7 @@ from fastapi import FastAPI from .blog import router as blog_router - +from .session import router as session_router def register_routers(app: FastAPI): - app.include_router(blog_router, prefix="") \ No newline at end of file + app.include_router(blog_router, prefix="") + app.include_router(session_router, prefix="") diff --git a/api/__pycache__/__init__.cpython-310.pyc b/api/__pycache__/__init__.cpython-310.pyc index 3d6dcfc..51d8d64 100644 Binary files a/api/__pycache__/__init__.cpython-310.pyc and b/api/__pycache__/__init__.cpython-310.pyc differ diff --git a/api/__pycache__/blog.cpython-310.pyc b/api/__pycache__/blog.cpython-310.pyc index f466a07..5f6706b 100644 Binary files a/api/__pycache__/blog.cpython-310.pyc and b/api/__pycache__/blog.cpython-310.pyc differ diff --git a/api/blog.py b/api/blog.py index 4cd2917..12449ff 100644 --- a/api/blog.py +++ b/api/blog.py @@ -3,6 +3,7 @@ from typing import List from fastapi import APIRouter, Depends, Query, Request from sqlalchemy.orm import Session +from config.auth import verify_token from schemas.blog import BlogResponse, BlogQuery, BlogCategoryResponse, BlogStatsResponse, \ BlogLatestResponse, BlogCommentCreate, BlogCommentResponse, BlogVisitResponse, BlogCreate, BlogUpdate from schemas.pagination import PageResult @@ -35,17 +36,17 @@ def query_blog_by_id(blog_id: int, db: Session = Depends(get_db)): @router.post("", summary="新增博客内容", response_model=bool) -def add_blog(blog: BlogCreate, db: Session = Depends(get_db)): +def add_blog(blog: BlogCreate, db: Session = Depends(get_db), _ = Depends(verify_token)): return blog_service.add_blog(db, blog) @router.put("/{blog_id}", summary="更新博客内容", response_model=bool) -def update_blog(blog_id: int, blog: BlogUpdate, db: Session = Depends(get_db)): +def update_blog(blog_id: int, blog: BlogUpdate, db: Session = Depends(get_db), _ = Depends(verify_token)): return blog_service.update_blog(db, blog_id, blog) @router.delete("/{blog_id}", summary="删除博客内容", response_model=bool) -def delete_blog(blog_id: int, db: Session = Depends(get_db)): +def delete_blog(blog_id: int, db: Session = Depends(get_db), _ = Depends(verify_token)): return blog_service.delete_blog(db, blog_id) diff --git a/api/session.py b/api/session.py new file mode 100644 index 0000000..1a459ca --- /dev/null +++ b/api/session.py @@ -0,0 +1,18 @@ +from fastapi import APIRouter, Depends +from fastapi.security import OAuth2PasswordRequestForm +from sqlalchemy.orm import Session + +from config.database import get_db +from schemas.session import SessionResponse +from service import session_service + +router = APIRouter( + prefix="/session", + tags=["会话"], + responses={404: {"description": "Not found"}} +) + + +@router.post("", summary="创建会话", response_model=SessionResponse) +def create(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)): + return session_service.create(db, form_data.username, form_data.password) diff --git a/config/__pycache__/auth.cpython-310.pyc b/config/__pycache__/auth.cpython-310.pyc index 264e224..022e18a 100644 Binary files a/config/__pycache__/auth.cpython-310.pyc and b/config/__pycache__/auth.cpython-310.pyc differ diff --git a/requirements.txt b/requirements.txt index b521df0..5fa9cc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -fastapi~=0.115.12 sqlalchemy~=2.0.41 pydantic~=2.11.4 PyJWT~=2.10.1 passlib~=1.7.4 loguru~=0.7.3 pydantic-settings~=2.9.1 pymysql~=1.1.1 uvicorn~=0.23.0 \ No newline at end of file +fastapi~=0.115.12 sqlalchemy~=2.0.41 pydantic~=2.11.4 PyJWT~=2.10.1 passlib~=1.7.4 loguru~=0.7.3 pydantic-settings~=2.9.1 pymysql~=1.1.1 python-multipart~=0.0.20 uvicorn~=0.23.0 # pip download -r requirements.txt -d ./packages --only-binary=:all: --platform manylinux2014_x86_64 -i https://pypi.tuna.tsinghua.edu.cn/simple \ No newline at end of file diff --git a/schemas/session.py b/schemas/session.py new file mode 100644 index 0000000..2300d1f --- /dev/null +++ b/schemas/session.py @@ -0,0 +1,6 @@ +from pydantic import BaseModel + + +class SessionResponse(BaseModel): + access_token: str + token_type: str diff --git a/service/session_service.py b/service/session_service.py new file mode 100644 index 0000000..c15fcf2 --- /dev/null +++ b/service/session_service.py @@ -0,0 +1,23 @@ +from sqlalchemy.orm import Session + +from schemas.session import SessionResponse +from config.auth import create_token, create_payload +from middleware.exceptions import AppException + + +def create(db: Session, username: str, password: str) -> SessionResponse: + # 1. 校验账户是否存在 + if username != "admin": + raise AppException(f"该账户{username}不存在") + + # 2. 校验密码是否正确 + if password != "19940822Cxx": + raise AppException("密码错误") + + return SessionResponse( + access_token=create_token(create_payload(username)), + token_type="Bearer" + ) + + + diff --git a/sys.stdout b/sys.stdout index abc25c4..18fd478 100644 --- a/sys.stdout +++ b/sys.stdout @@ -710,3 +710,107 @@ 2025-09-22 19:35:46.701 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} 2025-09-22 19:36:39.565 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 2025-09-22 19:36:39.565 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 13:38:24.061 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/ +2025-09-23 13:38:24.072 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 404 +2025-09-23 13:38:24.176 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/favicon.ico +2025-09-23 13:38:24.176 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 404 +2025-09-23 13:38:28.402 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:38:50.471 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:38:51.104 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json +2025-09-23 13:38:55.964 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 13:38:55.964 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 13:38:55.964 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 13:40:23.368 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 13:40:23.369 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 13:40:32.054 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/blog +2025-09-23 13:40:32.056 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 13:46:14.026 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:46:14.554 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json +2025-09-23 13:46:19.941 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:46:20.022 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json +2025-09-23 13:46:24.491 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:46:24.553 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json +2025-09-23 13:49:32.889 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:49:32.991 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json +2025-09-23 13:52:53.666 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:52:53.766 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json +2025-09-23 13:53:00.113 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs +2025-09-23 13:53:00.173 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json +2025-09-23 13:57:51.959 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 13:57:51.960 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 13:57:56.317 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 13:57:56.422 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 13:57:57.914 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 13:57:58.014 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 13:57:58.014 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 13:57:58.028 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/stats +2025-09-23 13:57:58.044 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/latest +2025-09-23 13:57:58.074 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 13:57:58.074 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 13:58:39.770 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 13:58:39.785 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 13:58:41.260 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 13:58:41.262 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 14:02:37.558 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session?name=estun&password=medical +2025-09-23 14:02:37.558 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'name': 'estun', 'password': 'medical'} +2025-09-23 14:02:37.560 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 422 +2025-09-23 14:03:42.464 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:03:42.466 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 422 +2025-09-23 14:06:05.092 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:06:05.095 | ERROR  | middleware.exceptions:global_exception_handler:32 - 业务异常: 该账户estun不存在 - 详情: None +2025-09-23 14:07:04.464 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:07:04.467 | ERROR  | middleware.exceptions:global_exception_handler:32 - 业务异常: 该账户admin不存在 - 详情: None +2025-09-23 14:07:53.591 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:07:53.596 | ERROR  | middleware.exceptions:global_exception_handler:32 - 业务异常: 该账户admin不存在 - 详情: None +2025-09-23 14:08:48.398 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:26:31.145 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:26:56.041 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:26:57.633 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:26:57.633 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:26:59.248 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 14:26:59.333 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 14:27:00.498 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 14:27:00.500 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 14:31:33.983 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:31:35.668 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:31:35.668 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:31:37.840 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 14:31:37.897 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 14:31:39.290 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 14:31:39.291 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 14:37:39.603 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:37:41.438 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:37:41.438 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:37:51.897 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 14:37:51.970 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 14:37:53.706 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 14:37:53.708 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 14:38:31.930 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:38:33.214 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:38:33.214 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:38:34.724 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 14:38:34.779 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 14:38:35.684 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 14:38:35.686 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 14:40:02.522 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 14:40:02.524 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401 +2025-09-23 14:40:12.792 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 14:40:12.816 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 14:40:24.342 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: POST http://127.0.0.1:8082/session +2025-09-23 14:40:25.690 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:40:25.691 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:40:26.966 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/content/631305371107398 +2025-09-23 14:40:27.033 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/comment/0 +2025-09-23 14:40:28.104 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/631305371107398 +2025-09-23 14:40:28.201 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:40:28.201 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:40:28.215 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/stats +2025-09-23 14:40:28.230 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/latest +2025-09-23 14:40:28.263 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:40:28.263 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:41:06.532 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:41:06.533 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:41:58.649 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 +2025-09-23 14:41:58.649 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} +2025-09-23 14:42:06.096 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: PUT http://127.0.0.1:8082/blog/21312 +2025-09-23 14:42:06.098 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 401