支持从.env同步管理员密码;新增reset_admin.py

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-15 11:29:12 +08:00
parent d244caddad
commit 471166bec3
4 changed files with 63 additions and 10 deletions
+2 -1
View File
@@ -6,9 +6,10 @@ DEBUG=false
# Flask Session 密钥(部署时务必改为随机字符串,deploy.sh 首次会自动生成) # Flask Session 密钥(部署时务必改为随机字符串,deploy.sh 首次会自动生成)
SECRET_KEY=change-this-to-a-random-secret-key SECRET_KEY=change-this-to-a-random-secret-key
# 初始管理员账号(仅首次初始化数据库时写入,之后请在「系统设置」修改密码 # 初始管理员(首次建库自动写入;已建库后修改需设 ADMIN_SYNC_FROM_ENV=true 并重启
ADMIN_USERNAME=admin ADMIN_USERNAME=admin
ADMIN_PASSWORD=change-me-on-first-login ADMIN_PASSWORD=change-me-on-first-login
ADMIN_SYNC_FROM_ENV=false
# 企业微信 Webhook(也可在系统设置页面修改) # 企业微信 Webhook(也可在系统设置页面修改)
WECHAT_WEBHOOK= WECHAT_WEBHOOK=
+8 -3
View File
@@ -91,14 +91,19 @@ HOST=0.0.0.0
PORT=6600 PORT=6600
SECRET_KEY=随机长字符串 SECRET_KEY=随机长字符串
ADMIN_USERNAME=admin ADMIN_USERNAME=admin
ADMIN_PASSWORD=首次登录密码 ADMIN_PASSWORD=你的密码
ADMIN_SYNC_FROM_ENV=false
WECHAT_WEBHOOK=企业微信机器人地址(可选) WECHAT_WEBHOOK=企业微信机器人地址(可选)
QUOTE_SOURCE=sina QUOTE_SOURCE=sina
``` ```
普通用户保持 `QUOTE_SOURCE=sina` 即可,无需配置同花顺 token **改密码说明**:账号存在 `futures.db` 里,改 `.env` 后不会自动生效
> 管理员密码首次从 `.env` 写入数据库并哈希存储,之后请在「系统设置」中修改 - **首次部署**:写好 `ADMIN_USERNAME` / `ADMIN_PASSWORD` 后启动即可
- **已部署后**:在 `.env``ADMIN_SYNC_FROM_ENV=true`,改密码后 `pm2 restart qihuo`;或在网页「系统设置」改密。
- **忘记密码**`source venv/bin/activate && python reset_admin.py`
普通用户保持 `QUOTE_SOURCE=sina` 即可。
### 5. PM2 启动 ### 5. PM2 启动
+29 -6
View File
@@ -17,7 +17,7 @@ from werkzeug.security import check_password_hash, generate_password_hash
from symbols import search_symbols, ths_to_codes from symbols import search_symbols, ths_to_codes
from market import get_price as market_get_price, set_ths_refresh_token, get_quote_source_label from market import get_price as market_get_price, set_ths_refresh_token, get_quote_source_label
load_dotenv() load_dotenv(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env"))
app = Flask(__name__) app = Flask(__name__)
app.secret_key = os.getenv("SECRET_KEY", "futures_monitor_default_secret") app.secret_key = os.getenv("SECRET_KEY", "futures_monitor_default_secret")
@@ -96,11 +96,7 @@ def init_db():
conn.commit() conn.commit()
conn.close() conn.close()
if not get_setting("admin_username"): sync_admin_from_env()
username = os.getenv("ADMIN_USERNAME", "admin")
password = os.getenv("ADMIN_PASSWORD", "admin123")
set_setting("admin_username", username)
set_setting("admin_password_hash", generate_password_hash(password))
if not get_setting("wechat_webhook") and os.getenv("WECHAT_WEBHOOK"): if not get_setting("wechat_webhook") and os.getenv("WECHAT_WEBHOOK"):
set_setting("wechat_webhook", os.getenv("WECHAT_WEBHOOK")) set_setting("wechat_webhook", os.getenv("WECHAT_WEBHOOK"))
@@ -109,6 +105,33 @@ def init_db():
set_setting("ths_refresh_token", os.getenv("THS_REFRESH_TOKEN")) set_setting("ths_refresh_token", os.getenv("THS_REFRESH_TOKEN"))
def sync_admin_from_env():
"""
从 .env 同步管理员账号。
- 首次建库:自动写入 ADMIN_USERNAME / ADMIN_PASSWORD
- 已建库后改 .env:需设 ADMIN_SYNC_FROM_ENV=true 并重启服务
"""
sync = os.getenv("ADMIN_SYNC_FROM_ENV", "false").lower() in ("1", "true", "yes")
env_username = os.getenv("ADMIN_USERNAME", "").strip()
env_password = os.getenv("ADMIN_PASSWORD", "").strip()
placeholder_passwords = {"", "change-me-on-first-login", "admin123"}
if not get_setting("admin_username"):
username = env_username or "admin"
password = env_password if env_password not in placeholder_passwords else "admin123"
set_setting("admin_username", username)
set_setting("admin_password_hash", generate_password_hash(password))
return
if not sync:
return
if env_username:
set_setting("admin_username", env_username)
if env_password and env_password not in placeholder_passwords:
set_setting("admin_password_hash", generate_password_hash(env_password))
init_db() init_db()
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
"""从 .env 重置管理员账号(服务器上忘记密码时使用)"""
import os
import sys
from dotenv import load_dotenv
from werkzeug.security import generate_password_hash
BASE = os.path.dirname(os.path.abspath(__file__))
load_dotenv(os.path.join(BASE, ".env"))
sys.path.insert(0, BASE)
from app import set_setting, get_setting # noqa: E402
username = os.getenv("ADMIN_USERNAME", "admin").strip() or "admin"
password = os.getenv("ADMIN_PASSWORD", "").strip()
if not password or password == "change-me-on-first-login":
print("请在 .env 中设置 ADMIN_PASSWORD 后再运行此脚本")
sys.exit(1)
old_username = get_setting("admin_username")
set_setting("admin_username", username)
set_setting("admin_password_hash", generate_password_hash(password))
print(f"已重置管理员: {username}(原账号: {old_username or ''}")