做 ip 防呆機制

This commit is contained in:
2025-08-01 13:17:32 +08:00
parent 2282eed9a1
commit a54ae31896
7 changed files with 1139 additions and 125 deletions

196
app/test/ip-test/page.tsx Normal file
View File

@@ -0,0 +1,196 @@
'use client'
import { useState } from 'react'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Globe, ExternalLink, Info, CheckCircle, AlertCircle } from 'lucide-react'
export default function IpTestPage() {
const [externalIp, setExternalIp] = useState<string | null>(null)
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const fetchExternalIp = async () => {
setLoading(true)
setError(null)
try {
const response = await fetch('https://api.ipify.org?format=json')
if (!response.ok) {
throw new Error('無法獲取外部IP')
}
const data = await response.json()
setExternalIp(data.ip)
} catch (error) {
console.error('Error fetching external IP:', error)
setError('無法獲取外部IP地址')
} finally {
setLoading(false)
}
}
return (
<div className="container mx-auto p-6 max-w-4xl space-y-6">
<div className="text-center">
<h1 className="text-3xl font-bold mb-2">IP </h1>
<p className="text-muted-foreground">IP地址</p>
</div>
{/* 說明 */}
<Alert>
<Info className="h-4 w-4" />
<AlertDescription>
<div className="font-medium mb-2"> 127.0.0.1</div>
<div className="text-sm space-y-1">
<div> </div>
<div> </div>
<div> IP檢測會更準確</div>
<div> 使IP</div>
</div>
</AlertDescription>
</Alert>
{/* 外部IP檢測 */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Globe className="w-5 h-5" />
IP檢測
</CardTitle>
<CardDescription>
IP地址
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center gap-4">
<Button
onClick={fetchExternalIp}
disabled={loading}
className="flex items-center gap-2"
>
<ExternalLink className="w-4 h-4" />
{loading ? '檢測中...' : '檢測真實IP'}
</Button>
{externalIp && (
<div className="flex items-center gap-2">
<span className="font-medium">IP:</span>
<Badge variant="default" className="flex items-center gap-1">
<CheckCircle className="w-3 h-3" />
{externalIp}
</Badge>
</div>
)}
</div>
{error && (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<div className="text-sm text-muted-foreground">
<p>IP地址就是你的真實公網IP</p>
<ul className="list-disc list-inside mt-2 space-y-1">
<li>IP白名單</li>
<li>IP檢測功能</li>
<li></li>
</ul>
</div>
</CardContent>
</Card>
{/* 測試方法 */}
<Card>
<CardHeader>
<CardTitle>IP的方法</CardTitle>
<CardDescription>IP檢測功能的方法</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-3">
<div>
<h4 className="font-medium mb-2">1. 使 ngrok </h4>
<div className="text-sm text-muted-foreground space-y-1">
<p> ngrok: <code className="bg-muted px-1 rounded">npm install -g ngrok</code></p>
<p> : <code className="bg-muted px-1 rounded">ngrok http 3000</code></p>
<p> 使 ngrok URL訪問你的應用</p>
<p> IP檢測功能</p>
</div>
</div>
<div>
<h4 className="font-medium mb-2">2. </h4>
<div className="text-sm text-muted-foreground space-y-1">
<p> VercelNetlify </p>
<p> IP檢測會更準確</p>
<p> IP白名單功能</p>
</div>
</div>
<div>
<h4 className="font-medium mb-2">3. 使</h4>
<div className="text-sm text-muted-foreground space-y-1">
<p> Nginx Apache </p>
<p> IP </p>
<p> IP檢測</p>
</div>
</div>
</div>
</CardContent>
</Card>
{/* 配置建議 */}
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div>
<h4 className="font-medium mb-2"></h4>
<div className="text-sm text-muted-foreground">
<p> <code className="bg-muted px-1 rounded">.env.local</code> </p>
<pre className="bg-muted p-2 rounded mt-2 text-xs">
{`# 禁用IP白名單檢查
ENABLE_IP_WHITELIST=false
# 或者允許本地IP
ALLOWED_IPS=127.0.0.1,192.168.1.0/24`}
</pre>
</div>
</div>
<div>
<h4 className="font-medium mb-2"></h4>
<div className="text-sm text-muted-foreground">
<p></p>
<pre className="bg-muted p-2 rounded mt-2 text-xs">
{`# 啟用IP白名單
ENABLE_IP_WHITELIST=true
# 設置允許的IP地址
ALLOWED_IPS=你的真實IP地址,其他允許的IP`}
</pre>
</div>
</div>
</div>
</CardContent>
</Card>
{/* 快速連結 */}
<div className="flex justify-center gap-4">
<Button variant="outline" onClick={() => window.open('/test/ip-debug', '_blank')}>
<Globe className="w-4 h-4 mr-2" />
IP調試
</Button>
<Button variant="outline" onClick={() => window.open('/api/ip', '_blank')}>
<ExternalLink className="w-4 h-4 mr-2" />
IP API
</Button>
</div>
</div>
)
}