fix(weixin_ilink): 换码阈值5s->60s——码未过期一律复用,防前端高频login-qr砍确认会话
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

This commit is contained in:
Aska committed 2026-09-08 01:49:20 +08:00
1 parent 851c8a31ce
commit 8d44bba14a
2 files changed
+12 -7

No files matched your search

+10 -5
View File
@@ -133,13 +133,18 @@ func (a *Adapter) StartLogin(ctx context.Context) (LoginQR, error) {
a.log.Info("weixin_ilink: login in progress, reusing qrcode", "phase", sess.currentPhase())
return LoginQR{Qrcode: sess.qrcode, Image: sess.image}, nil
}
// A literal double-click within the reuse window: serve the same code.
if time.Since(sess.startedAt) < qrReuseWindow {
// Serve the same code while it is still fresh OR already scanned — always
// reuse, never swap, so an in-progress bind (which WeChat may be confirming
// right now) is never dropped. A frontend flooding login-qr calls therefore
// cannot cancel the session under the user's scan. Only a genuinely stale
// (>60s server TTL) and never-scanned code is re-minted.
if time.Since(sess.startedAt) < 60*time.Second {
a.log.Info("weixin_ilink: login in progress, reusing qrcode", "phase", sess.currentPhase())
return LoginQR{Qrcode: sess.qrcode, Image: sess.image}, nil
}
// Not scanned yet and past the reuse window: mint a fresh code, cancelling the
// old (unscanned) poll. failLogin guards a cancelled goroutine from clobbering
// the new session's state.
// Code stale (>60s) and never scanned: mint a fresh one, cancelling the old
// (expired, unscanned) poll. failLogin guards a cancelled goroutine from
// clobbering the new session's state.
a.log.Info("weixin_ilink: previous qrcode not scanned, minting a fresh one")
if sess.cancel != nil {
sess.cancel()
@@ -75,7 +75,7 @@ func TestStartLogin_ScanedPastWindowReusesQR(t *testing.T) {
// could keep the QR. Then a refresh must still reuse it.
ad.loginMu.Lock()
if ad.loginSession != nil {
ad.loginSession.startedAt = time.Now().Add(-(qrReuseWindow + time.Second))
ad.loginSession.startedAt = time.Now().Add(-(60*time.Second + time.Second))
}
ad.loginMu.Unlock()
@@ -128,7 +128,7 @@ func TestStartLogin_WaitingPastWindowReMints(t *testing.T) {
ad.loginMu.Lock()
if ad.loginSession != nil {
ad.loginSession.startedAt = time.Now().Add(-(qrReuseWindow + time.Second))
ad.loginSession.startedAt = time.Now().Add(-(60*time.Second + time.Second))
}
ad.loginMu.Unlock()