D109续③ · 登录改为代码仓库账号密码(告别长Token)

This commit is contained in:
铸渊 2026-05-21 14:26:40 +00:00
parent f5033df659
commit ff38c723ca
2 changed files with 67 additions and 12 deletions

View File

@ -33,7 +33,7 @@ from engine import (
class Settings:
APP_NAME = "语料采集系统 Corpus Agent"
VERSION = "1.0.1"
VERSION = "1.1.0"
# 存储路径
DATA_DIR = Path(os.environ.get("CORPUS_DATA_DIR", "./data"))
@ -85,6 +85,10 @@ class CorpusSave(BaseModel):
class LoginRequest(BaseModel):
gitea_token: str
class PasswordLoginRequest(BaseModel):
username: str
password: str
class ChatRequest(BaseModel):
message: str
persona: str = "zhuyuan" # zhuyuan | shuangyan
@ -294,6 +298,50 @@ async def login(req: LoginRequest):
}
}
@app.post("/api/auth/login/password")
async def login_with_password(req: PasswordLoginRequest):
"""使用代码仓库账号密码登录(复用首页的 /api/verify 接口)"""
import urllib.request
if not req.username.strip() or not req.password:
raise HTTPException(400, "账号和密码不能为空")
try:
# 调用本地验证接口nginx: /api/verify → 127.0.0.1:3905/verify
verify_data = json.dumps({"user": req.username, "password": req.password}).encode()
verify_req = urllib.request.Request(
"http://127.0.0.1:3905/verify",
data=verify_data,
headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(verify_req, timeout=10) as resp:
result = json.loads(resp.read().decode())
if not result.get("ok"):
raise HTTPException(401, "账号或密码错误")
username = result.get("username", req.username)
except HTTPException:
raise
except Exception as e:
raise HTTPException(500, f"验证服务不可达: {str(e)}")
token = create_session(username)
# 统计现有语料
corpus = load_corpus(username)
return {
"ok": True,
"token": token,
"username": username,
"stats": {
"total_samples": len(corpus),
"total_chars": sum(len(json.dumps(s, ensure_ascii=False)) for s in corpus),
}
}
@app.get("/api/auth/check")
async def check_session(token: str = Query(...)):
username = get_user_from_token(token)

View File

@ -121,21 +121,24 @@
<div class="header">
<h1>🧠 语料采集系统 · Corpus Agent</h1>
<p>自动采集 · 脱敏 · 格式化 · 对话式语料分析</p>
<div class="version">v1.0.1 · 国作登字-2026-A-00037559</div>
<div class="version">v1.1.0 · 国作登字-2026-A-00037559</div>
</div>
<!-- Login -->
<div class="card" id="login-section">
<div class="login-box">
<h2 style="margin-bottom:8px">登录</h2>
<p style="color:#666; font-size:13px; margin-bottom:20px">
使用 Gitea Access Token 登录
<p style="color:#666; font-size:13px; margin-bottom:8px">
使用代码仓库账号登录
</p>
<input type="password" id="token-input" placeholder="输入 Gitea Access Token">
<input type="text" id="login-user" placeholder="Gitea 账号" style="width:260px" onkeydown="if(event.key==='Enter')login()">
<br>
<input type="password" id="login-pass" placeholder="密码" style="width:260px" onkeydown="if(event.key==='Enter')login()">
<br>
<button class="btn btn-primary" onclick="login()">登录</button>
<div id="login-error" style="color:#ef4444;font-size:13px;margin-top:8px;display:none"></div>
<p style="color:#999; font-size:12px; margin-top:12px">
访问 <a href="https://guanghulab.com/user/settings/applications" target="_blank" style="color:#4a6cf7">Gitea → 设置 → 应用</a> 创建 Token
<a href="https://guanghulab.com/" target="_blank" style="color:#4a6cf7">光湖联邦首页</a> 使用同一套账号
</p>
</div>
</div>
@ -288,7 +291,7 @@
<!-- Footer -->
<div class="footer">
语料采集系统 v1.0.1 · 铸渊 · ICE-GL-ZY001 · 国作登字-2026-A-00037559
语料采集系统 v1.1.0 · 铸渊 · ICE-GL-ZY001 · 国作登字-2026-A-00037559
</div>
</div>
@ -311,18 +314,22 @@ async function api(method, path, body) {
// ─── Login ─────────────────────────────────────────────────
async function login() {
const t = document.getElementById('token-input').value.trim();
if (!t) return alert('请输入Token');
const r = await fetch(`${API}/api/auth/login`, {
const user = document.getElementById('login-user').value.trim();
const pass = document.getElementById('login-pass').value;
const errEl = document.getElementById('login-error');
if (!user || !pass) { errEl.textContent = '请输入账号和密码'; errEl.style.display = 'block'; return; }
errEl.style.display = 'none';
const r = await fetch(`${API}/api/auth/login/password`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({gitea_token: t})
body: JSON.stringify({username: user, password: pass})
});
const d = await r.json();
if (!d.ok) return alert('登录失败: ' + JSON.stringify(d));
if (!d.ok) { errEl.textContent = d.detail || '登录失败'; errEl.style.display = 'block'; return; }
token = d.token;
username = d.username;
localStorage.setItem('corpus_token', token);
document.getElementById('login-pass').value = '';
document.getElementById('login-section').classList.add('hidden');
document.getElementById('main-section').classList.remove('hidden');
document.getElementById('display-name').textContent = username;