mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 08:31:55 +08:00
feat(auth): Add authentication to cache management API and frontend
- Implement token-based authentication for cache-related API endpoints - Add authorization headers to frontend fetch requests - Handle unauthorized access by redirecting to login page - Improve security for cache configuration and management routes
This commit is contained in:
parent
8a910d9d91
commit
c51d4869ba
8
main.go
8
main.go
@ -87,6 +87,14 @@ func main() {
|
|||||||
proxyHandler.AuthMiddleware(handler.NewCacheAdminHandler(proxyHandler.Cache, mirrorHandler.Cache, fixedPathCache).SetCacheEnabled)(w, r)
|
proxyHandler.AuthMiddleware(handler.NewCacheAdminHandler(proxyHandler.Cache, mirrorHandler.Cache, fixedPathCache).SetCacheEnabled)(w, r)
|
||||||
case "/admin/api/cache/clear":
|
case "/admin/api/cache/clear":
|
||||||
proxyHandler.AuthMiddleware(handler.NewCacheAdminHandler(proxyHandler.Cache, mirrorHandler.Cache, fixedPathCache).ClearCache)(w, r)
|
proxyHandler.AuthMiddleware(handler.NewCacheAdminHandler(proxyHandler.Cache, mirrorHandler.Cache, fixedPathCache).ClearCache)(w, r)
|
||||||
|
case "/admin/api/cache/config":
|
||||||
|
if r.Method == http.MethodGet {
|
||||||
|
proxyHandler.AuthMiddleware(handler.NewCacheAdminHandler(proxyHandler.Cache, mirrorHandler.Cache, fixedPathCache).GetCacheConfig)(w, r)
|
||||||
|
} else if r.Method == http.MethodPost {
|
||||||
|
proxyHandler.AuthMiddleware(handler.NewCacheAdminHandler(proxyHandler.Cache, mirrorHandler.Cache, fixedPathCache).UpdateCacheConfig)(w, r)
|
||||||
|
} else {
|
||||||
|
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
}
|
}
|
||||||
|
95
web/app/dashboard/cache/page.tsx
vendored
95
web/app/dashboard/cache/page.tsx
vendored
@ -7,6 +7,7 @@ import { useToast } from "@/components/ui/use-toast"
|
|||||||
import { Switch } from "@/components/ui/switch"
|
import { Switch } from "@/components/ui/switch"
|
||||||
import { Input } from "@/components/ui/input"
|
import { Input } from "@/components/ui/input"
|
||||||
import { Label } from "@/components/ui/label"
|
import { Label } from "@/components/ui/label"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
interface CacheStats {
|
interface CacheStats {
|
||||||
total_items: number
|
total_items: number
|
||||||
@ -54,10 +55,28 @@ export default function CachePage() {
|
|||||||
const [configs, setConfigs] = useState<CacheConfigs | null>(null)
|
const [configs, setConfigs] = useState<CacheConfigs | null>(null)
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const { toast } = useToast()
|
const { toast } = useToast()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const fetchStats = useCallback(async () => {
|
const fetchStats = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/admin/api/cache/stats")
|
const token = localStorage.getItem("token")
|
||||||
|
if (!token) {
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch("/admin/api/cache/stats", {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.status === 401) {
|
||||||
|
localStorage.removeItem("token")
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.ok) throw new Error("获取缓存统计失败")
|
if (!response.ok) throw new Error("获取缓存统计失败")
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
setStats(data)
|
setStats(data)
|
||||||
@ -70,11 +89,28 @@ export default function CachePage() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}, [toast])
|
}, [toast, router])
|
||||||
|
|
||||||
const fetchConfigs = useCallback(async () => {
|
const fetchConfigs = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/admin/api/cache/config")
|
const token = localStorage.getItem("token")
|
||||||
|
if (!token) {
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch("/admin/api/cache/config", {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.status === 401) {
|
||||||
|
localStorage.removeItem("token")
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.ok) throw new Error("获取缓存配置失败")
|
if (!response.ok) throw new Error("获取缓存配置失败")
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
setConfigs(data)
|
setConfigs(data)
|
||||||
@ -85,7 +121,7 @@ export default function CachePage() {
|
|||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [toast])
|
}, [toast, router])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 立即获取一次数据
|
// 立即获取一次数据
|
||||||
@ -99,12 +135,27 @@ export default function CachePage() {
|
|||||||
|
|
||||||
const handleToggleCache = async (type: "proxy" | "mirror" | "fixedPath", enabled: boolean) => {
|
const handleToggleCache = async (type: "proxy" | "mirror" | "fixedPath", enabled: boolean) => {
|
||||||
try {
|
try {
|
||||||
|
const token = localStorage.getItem("token")
|
||||||
|
if (!token) {
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch("/admin/api/cache/enable", {
|
const response = await fetch("/admin/api/cache/enable", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
body: JSON.stringify({ type, enabled }),
|
body: JSON.stringify({ type, enabled }),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (response.status === 401) {
|
||||||
|
localStorage.removeItem("token")
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.ok) throw new Error("切换缓存状态失败")
|
if (!response.ok) throw new Error("切换缓存状态失败")
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
@ -124,12 +175,27 @@ export default function CachePage() {
|
|||||||
|
|
||||||
const handleUpdateConfig = async (type: "proxy" | "mirror" | "fixedPath", config: CacheConfig) => {
|
const handleUpdateConfig = async (type: "proxy" | "mirror" | "fixedPath", config: CacheConfig) => {
|
||||||
try {
|
try {
|
||||||
|
const token = localStorage.getItem("token")
|
||||||
|
if (!token) {
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch("/admin/api/cache/config", {
|
const response = await fetch("/admin/api/cache/config", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
body: JSON.stringify({ type, config }),
|
body: JSON.stringify({ type, config }),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (response.status === 401) {
|
||||||
|
localStorage.removeItem("token")
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.ok) throw new Error("更新缓存配置失败")
|
if (!response.ok) throw new Error("更新缓存配置失败")
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
@ -149,12 +215,27 @@ export default function CachePage() {
|
|||||||
|
|
||||||
const handleClearCache = async (type: "proxy" | "mirror" | "fixedPath" | "all") => {
|
const handleClearCache = async (type: "proxy" | "mirror" | "fixedPath" | "all") => {
|
||||||
try {
|
try {
|
||||||
|
const token = localStorage.getItem("token")
|
||||||
|
if (!token) {
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch("/admin/api/cache/clear", {
|
const response = await fetch("/admin/api/cache/clear", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
body: JSON.stringify({ type }),
|
body: JSON.stringify({ type }),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (response.status === 401) {
|
||||||
|
localStorage.removeItem("token")
|
||||||
|
router.push("/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.ok) throw new Error("清理缓存失败")
|
if (!response.ok) throw new Error("清理缓存失败")
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user