oa-ai/src/app/api/auth/login/route.ts

49 lines
1.8 KiB
TypeScript

import { NextResponse } from 'next/server'
import { cookies } from 'next/headers'
import { signSharedJwt, sharedCookieConfig } from '@/lib/jwt'
import { ldapAuth, isLldapAdmin } from '@/lib/ldap'
import { writeAuditLog } from '@/lib/audit'
import { syncUserToAllSites } from '@/lib/sync-user'
export async function POST(request: Request) {
try {
const { username, password } = await request.json()
if (!username || !password) {
return NextResponse.json({ error: '请输入用户名和密码' }, { status: 400 })
}
const result = await ldapAuth(username, password)
if (!result.success) {
if (result.unreachable) {
return NextResponse.json({ error: '认证服务暂时不可用,请稍后再试' }, { status: 503 })
}
return NextResponse.json({ error: '用户名或密码错误' }, { status: 401 })
}
const token = signSharedJwt({ username: result.username!, displayName: result.displayName! })
const cfg = sharedCookieConfig()
const cookieStore = await cookies()
cookieStore.set(cfg.name, token, cfg)
// 审计日志
try {
writeAuditLog({
username: result.username!,
action: 'login',
details: { method: 'ldap', displayName: result.displayName },
ipAddress: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || 'unknown',
})
} catch { /* 审计日志失败不影响登录 */ }
// 跨站点角色同步(不阻塞响应)
const role = (await isLldapAdmin(result.username!)) ? 'admin' : 'viewer'
syncUserToAllSites(result.username!, result.displayName!, role).catch(() => {})
return NextResponse.json({
user: { username: result.username, displayName: result.displayName },
})
} catch {
return NextResponse.json({ error: '登录失败' }, { status: 500 })
}
}