# --- 简单登录鉴权(单用户;账密可用环境变量覆盖,默认 Simba / Simba+0322)---
# 前端登录后持 token;所有 /api/*(除登录接口)必须带有效 token,否则 401。
+# token 为 HMAC 签名、永久有效(无过期);secret 固定故服务重启不失效。
# 改密码:设置环境变量 WORDS_PASSWORD 或告诉我直接在后端改默认值。
+# 注意:token 签名与密码无关,改密码不会让已登录设备掉线;如需强制全部下线,改 AUTH_SECRET 即可。
AUTH_USERNAME = os.environ.get("WORDS_USERNAME", "Simba")
AUTH_PASSWORD = os.environ.get("WORDS_PASSWORD", "Simba+0322")
AUTH_SECRET = os.environ.get("WORDS_AUTH_SECRET", "words-fixed-secret-change-in-prod-7f3a9c")
-TOKEN_TTL_SECONDS = 30 * 24 * 3600 # 30 天
def _b64url(b: bytes) -> str:
def create_token(username: str) -> str:
- """签发 HMAC 签名 token:payload(username:expiry).sig,secret 固定故重启不失效。"""
- expiry = int(datetime.datetime.now().timestamp()) + TOKEN_TTL_SECONDS
- payload = f"{username}:{expiry}".encode()
+ """签发 HMAC 签名 token(永久有效,无过期):payload(username).sig。"""
+ payload = username.encode()
sig = hmac.new(AUTH_SECRET.encode(), payload, hashlib.sha256).digest()
return f"{_b64url(payload)}.{_b64url(sig)}"
def verify_token(token: str):
- """校验 token 签名与过期,返回 username 或 None。"""
+ """校验 token 签名(永久有效,无过期检查),返回 username 或 None。
+ 兼容旧格式 payload(username:expiry)。"""
if not token:
return None
try:
expected = hmac.new(AUTH_SECRET.encode(), payload, hashlib.sha256).digest()
if not hmac.compare_digest(sig, expected):
return None
- username, expiry = payload.decode().split(":")
- if int(expiry) < datetime.datetime.now().timestamp():
- return None
- return username
+ return payload.decode().split(":")[0]
except Exception:
return None