登录增加fail2ban机制
This commit is contained in:
@@ -4,6 +4,12 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
import { parseAuthInfo } from '@/lib/auth';
|
||||
import { getConfig } from '@/lib/config';
|
||||
import { db } from '@/lib/db';
|
||||
import {
|
||||
checkLoginBan,
|
||||
getLoginClientIp,
|
||||
recordLoginFailure,
|
||||
recordLoginSuccess,
|
||||
} from '@/lib/login-fail2ban';
|
||||
import {
|
||||
generateRefreshToken,
|
||||
generateTokenId,
|
||||
@@ -177,6 +183,20 @@ function getDeviceInfo(request: NextRequest): string {
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const clientIp = getLoginClientIp(req);
|
||||
const banStatus = checkLoginBan(clientIp);
|
||||
if (banStatus.banned) {
|
||||
return NextResponse.json(
|
||||
{ error: '登录失败次数过多,请稍后再试' },
|
||||
{
|
||||
status: 429,
|
||||
headers: banStatus.retryAfterSeconds
|
||||
? { 'Retry-After': String(banStatus.retryAfterSeconds) }
|
||||
: undefined,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// 获取站点配置
|
||||
const adminConfig = await getConfig();
|
||||
const siteConfig = adminConfig.SiteConfig;
|
||||
@@ -206,12 +226,15 @@ export async function POST(req: NextRequest) {
|
||||
}
|
||||
|
||||
if (password !== envPassword) {
|
||||
recordLoginFailure(clientIp);
|
||||
return NextResponse.json(
|
||||
{ ok: false, error: '密码错误' },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
recordLoginSuccess(clientIp);
|
||||
|
||||
// 验证成功,设置认证cookie
|
||||
const username = process.env.USERNAME || 'default';
|
||||
const deviceInfo = getDeviceInfo(req);
|
||||
@@ -279,6 +302,8 @@ export async function POST(req: NextRequest) {
|
||||
username === process.env.USERNAME &&
|
||||
password === process.env.PASSWORD
|
||||
) {
|
||||
recordLoginSuccess(clientIp);
|
||||
|
||||
// 验证成功,设置认证cookie
|
||||
const deviceInfo = getDeviceInfo(req);
|
||||
const cookieValue = await generateAuthCookie(
|
||||
@@ -302,6 +327,7 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
return response;
|
||||
} else if (username === process.env.USERNAME) {
|
||||
recordLoginFailure(clientIp);
|
||||
return NextResponse.json({ error: '用户名或密码错误' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -326,12 +352,15 @@ export async function POST(req: NextRequest) {
|
||||
}
|
||||
|
||||
if (!pass) {
|
||||
recordLoginFailure(clientIp);
|
||||
return NextResponse.json(
|
||||
{ error: '用户名或密码错误' },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
recordLoginSuccess(clientIp);
|
||||
|
||||
// 验证成功,设置认证cookie
|
||||
const deviceInfo = getDeviceInfo(req);
|
||||
const cookieValue = await generateAuthCookie(
|
||||
|
||||
Reference in New Issue
Block a user