Files
accredit/main.go

186 lines
4.1 KiB
Go
Raw Permalink Normal View History

2025-10-18 20:04:03 +08:00
package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"strings"
"time"
)
// User 用户数据结构
type User struct {
IP string `json:"ip"`
Username string `json:"username"`
ExpiryDate string `json:"expiryDate"`
Phone string `json:"phone"`
}
// UserData 用户数据容器
type UserData struct {
Users []User `json:"users"`
}
// APIResponse API响应结构
type APIResponse struct {
Expiry string `json:"expiry"`
ServerTime string `json:"serverTime"`
}
// getClientIP 获取客户端真实IP地址
func getClientIP(r *http.Request) string {
// 优先检查代理头
if xForwardedFor := r.Header.Get("X-Forwarded-For"); xForwardedFor != "" {
// X-Forwarded-For 可能包含多个IP取第一个
ips := strings.Split(xForwardedFor, ",")
if len(ips) > 0 {
return strings.TrimSpace(ips[0])
}
}
if xRealIP := r.Header.Get("X-Real-IP"); xRealIP != "" {
return xRealIP
}
if xClientIP := r.Header.Get("X-Client-IP"); xClientIP != "" {
return xClientIP
}
// 从RemoteAddr获取IP
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return r.RemoteAddr
}
// 处理IPv6回环地址
if ip == "::1" {
return "127.0.0.1"
}
// 移除IPv6前缀
if strings.HasPrefix(ip, "::ffff:") {
return strings.TrimPrefix(ip, "::ffff:")
}
return ip
}
// loadUserData 加载用户数据
func loadUserData() ([]User, error) {
data, err := os.ReadFile("users.json")
if err != nil {
return nil, err
}
var userData UserData
err = json.Unmarshal(data, &userData)
if err != nil {
return nil, err
}
return userData.Users, nil
}
// findUserByIP 根据IP查找用户
func findUserByIP(users []User, ip string) *User {
for _, user := range users {
if user.IP == ip {
return &user
}
}
return nil
}
// setCORSHeaders 设置CORS头
func setCORSHeaders(w http.ResponseWriter) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
}
// healthHandler 健康检查处理器
func healthHandler(w http.ResponseWriter, r *http.Request) {
setCORSHeaders(w)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
response := map[string]interface{}{
"status": "ok",
"time": time.Now().Format(time.RFC3339),
}
json.NewEncoder(w).Encode(response)
}
// checkExpiryHandler 检查到期时间处理器
func checkExpiryHandler(w http.ResponseWriter, r *http.Request) {
setCORSHeaders(w)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
// 获取客户端IP
clientIP := getClientIP(r)
log.Printf("收到来自 %s 的请求", clientIP)
// 获取当前服务器时间
serverTime := time.Now().Format(time.RFC3339)
// 加载用户数据
users, err := loadUserData()
if err != nil {
log.Printf("读取用户数据失败: %v", err)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{})
return
}
// 查找用户
user := findUserByIP(users, clientIP)
if user == nil {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{})
return
}
// 找到用户,返回到期时间
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(APIResponse{
Expiry: user.ExpiryDate,
ServerTime: serverTime,
})
}
func main() {
// 定义命令行参数
portFlag := flag.String("port", "3763", "服务器端口号")
flag.Parse()
// 设置路由
http.HandleFunc("/health", healthHandler)
http.HandleFunc("/api/check-expiry", checkExpiryHandler)
port := ":" + *portFlag
fmt.Printf("服务器运行在端口 %s\n", port)
fmt.Printf("健康检查: http://localhost%s/health\n", port)
fmt.Printf("API接口: http://localhost%s/api/check-expiry\n", port)
// 启动服务器
log.Fatal(http.ListenAndServe(port, nil))
}