持久化二维码状态,以防止多节点不同步

This commit is contained in:
mtvpls
2026-05-30 21:39:09 +08:00
parent e055f18174
commit 30554fcd77
5 changed files with 92 additions and 15 deletions
+6 -3
View File
@@ -1,12 +1,15 @@
import { NextRequest, NextResponse } from 'next/server';
import { getQrLoginSession } from '@/lib/qr-login/store';
import { getQrLoginSession, saveQrLoginSession } from '@/lib/qr-login/store';
export const runtime = 'nodejs';
export async function POST(request: NextRequest) {
const { token } = await request.json();
const session = getQrLoginSession(token);
if (session) session.status = 'cancelled';
const session = await getQrLoginSession(token);
if (session) {
session.status = 'cancelled';
await saveQrLoginSession(session);
}
return NextResponse.json({ ok: true });
}
+3 -2
View File
@@ -1,13 +1,13 @@
import { NextRequest, NextResponse } from 'next/server';
import { getAuthInfoFromCookie } from '@/lib/auth';
import { getQrLoginSession } from '@/lib/qr-login/store';
import { getQrLoginSession, saveQrLoginSession } from '@/lib/qr-login/store';
export const runtime = 'nodejs';
export async function POST(request: NextRequest) {
const { token } = await request.json();
const session = getQrLoginSession(token);
const session = await getQrLoginSession(token);
if (!session || session.status === 'expired') return NextResponse.json({ error: '二维码已过期' }, { status: 410 });
if (session.status === 'cancelled' || session.status === 'used') return NextResponse.json({ error: '二维码不可用' }, { status: 400 });
@@ -18,5 +18,6 @@ export async function POST(request: NextRequest) {
session.status = 'confirmed';
session.authToken = authCookie;
session.userAgent = request.headers.get('user-agent') || '';
await saveQrLoginSession(session);
return NextResponse.json({ ok: true, status: 'confirmed' });
}
+1 -1
View File
@@ -5,7 +5,7 @@ import { createQrLoginSession } from '@/lib/qr-login/store';
export const runtime = 'nodejs';
export async function POST(request: NextRequest) {
const session = createQrLoginSession();
const session = await createQrLoginSession();
const origin = new URL(request.url).origin;
const qrUrl = `${origin}/qr-login?token=${encodeURIComponent(session.token)}`;
return NextResponse.json({ token: session.token, qrUrl, expiresAt: session.expiresAt, ttl: 120 });
+3 -2
View File
@@ -1,16 +1,17 @@
import { NextRequest, NextResponse } from 'next/server';
import { getQrLoginSession } from '@/lib/qr-login/store';
import { getQrLoginSession, saveQrLoginSession } from '@/lib/qr-login/store';
export const runtime = 'nodejs';
export async function GET(request: NextRequest) {
const token = new URL(request.url).searchParams.get('token');
const session = getQrLoginSession(token);
const session = await getQrLoginSession(token);
if (!session) return NextResponse.json({ status: 'expired' });
if (session.status === 'confirmed' && session.authToken) {
session.status = 'used';
await saveQrLoginSession(session);
const response = NextResponse.json({ status: 'confirmed' });
const expires = new Date();
expires.setDate(expires.getDate() + 60);