Files
wish-pool/middleware.ts
aken1023 2282eed9a1 增加ip 的白名單
總共7個IP地址,分佈在4個地點:
岡山:1個IP
汐止:2個IP
新竹:2個IP
璟茂:2個IP
2025-08-01 12:59:44 +08:00

123 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { isIpAllowed, getClientIp } from '@/lib/ip-utils'
export function middleware(request: NextRequest) {
// 檢查是否啟用IP白名單
const enableIpWhitelist = process.env.ENABLE_IP_WHITELIST === 'true'
if (!enableIpWhitelist) {
return NextResponse.next()
}
// 獲取客戶端IP
const clientIp = getClientIp(request)
// 獲取允許的IP列表
const allowedIps = process.env.ALLOWED_IPS || ''
// 檢查IP是否被允許
if (!isIpAllowed(clientIp, allowedIps)) {
// 記錄被拒絕的訪問
console.warn(`Access denied for IP: ${clientIp} - Path: ${request.nextUrl.pathname}`)
// 返回403禁止訪問頁面
return new NextResponse(
`
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>訪問被拒絕</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: white;
}
.container {
text-align: center;
background: rgba(255, 255, 255, 0.1);
padding: 3rem;
border-radius: 1rem;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
max-width: 500px;
margin: 1rem;
}
h1 {
font-size: 2rem;
margin-bottom: 1rem;
color: #ff6b6b;
}
p {
font-size: 1.1rem;
line-height: 1.6;
margin-bottom: 1rem;
opacity: 0.9;
}
.ip-info {
background: rgba(255, 255, 255, 0.1);
padding: 1rem;
border-radius: 0.5rem;
margin: 1rem 0;
font-family: 'Courier New', monospace;
}
.contact {
font-size: 0.9rem;
opacity: 0.7;
margin-top: 2rem;
}
</style>
</head>
<body>
<div class="container">
<h1>🚫 訪問被拒絕</h1>
<p>很抱歉您的IP地址不在允許的訪問列表中。</p>
<div class="ip-info">
<strong>您的IP地址</strong><br>
${clientIp}
</div>
<p>如果您認為這是一個錯誤,請聯繫系統管理員。</p>
<div class="contact">
錯誤代碼403 Forbidden<br>
時間:${new Date().toLocaleString('zh-TW')}
</div>
</div>
</body>
</html>
`,
{
status: 403,
headers: {
'Content-Type': 'text/html; charset=utf-8',
},
}
)
}
// IP檢查通過繼續處理請求
return NextResponse.next()
}
// 配置中間件適用的路徑
export const config = {
matcher: [
/*
* 匹配所有路徑,除了:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - icon.png (icon file)
*/
'/((?!api|_next/static|_next/image|favicon.ico|icon.png).*)',
],
}