diff --git a/app/.env b/app/.env index c408cc8..d6da4c9 100644 --- a/app/.env +++ b/app/.env @@ -19,4 +19,8 @@ LOG_LEVEL=INFO # 端口数==条数 从172.30.168.2开始 PORT_NUM=10 -MAX_ONLINE=10000 \ No newline at end of file +MAX_ONLINE=10000 + +ADMIN_USERNAME=heping +ADMIN_PASSWORD=He_Ping551 +SESSION_SECRET=sinehiunsdkfi \ No newline at end of file diff --git a/app/config.py b/app/config.py index fa5465a..9af6d11 100644 --- a/app/config.py +++ b/app/config.py @@ -17,6 +17,10 @@ class Settings(BaseModel): log_level: str = os.getenv("LOG_LEVEL", "INFO") port_num: int = int(os.getenv("PORT_NUM", 3)) max_online: int = int(os.getenv("MAX_ONLINE", 3)) + # 前台登录配置 + admin_username: str = os.getenv("ADMIN_USERNAME", "admin") + admin_password: str = os.getenv("ADMIN_PASSWORD", "admin") + session_secret: str = os.getenv("SESSION_SECRET", "change-me-please") settings = Settings() diff --git a/app/main.py b/app/main.py index 1b1b0af..30caabc 100644 --- a/app/main.py +++ b/app/main.py @@ -1,15 +1,19 @@ -from fastapi import FastAPI, Request +from fastapi import FastAPI, Request, Form from fastapi.templating import Jinja2Templates from fastapi.staticfiles import StaticFiles -from fastapi.responses import HTMLResponse +from fastapi.responses import HTMLResponse, RedirectResponse from .config import settings from .routers.proxy import router as proxy_router +from starlette.middleware.sessions import SessionMiddleware app = FastAPI(title="EIP Rotation Service") # 设置模板目录 templates = Jinja2Templates(directory="app/templates") +# 会话中间件(用于简单登录态) +app.add_middleware(SessionMiddleware, secret_key=settings.session_secret) + @app.get("/health") def health_check(): @@ -19,6 +23,8 @@ def health_check(): @app.get("/", response_class=HTMLResponse) async def index(request: Request, id: str = None): """主页 - IP轮换控制面板""" + if not request.session.get("authenticated"): + return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("index.html", { "request": request, "client_id": id or "1" # 默认ID为1 @@ -28,3 +34,23 @@ async def index(request: Request, id: str = None): app.include_router(proxy_router, prefix="/proxy", tags=["proxy"]) +@app.get("/login", response_class=HTMLResponse) +async def login_page(request: Request): + return templates.TemplateResponse("login.html", {"request": request, "error": None}) + + +@app.post("/login") +async def login_submit(request: Request, username: str = Form(...), password: str = Form(...)): + if username == settings.admin_username and password == settings.admin_password: + request.session["authenticated"] = True + return RedirectResponse(url="/", status_code=302) + # 登录失败,回到登录页并提示 + return templates.TemplateResponse("login.html", {"request": request, "error": "用户名或密码错误"}, status_code=401) + + +@app.get("/logout") +async def logout(request: Request): + request.session.clear() + return RedirectResponse(url="/login", status_code=302) + + diff --git a/app/templates/login.html b/app/templates/login.html new file mode 100644 index 0000000..e1d3fe1 --- /dev/null +++ b/app/templates/login.html @@ -0,0 +1,47 @@ + + + + + + 登录 - EIP 控制面板 + + + + + +
+

登录

+

进入 EIP IP 轮换控制面板

+
+ + + + + +
+
{{ error }}
+
+ + + +