feat: 客户端授权防护——响应签名/激活令牌/宽限期/换座限制/在线清扫/疑似共享标记
This commit is contained in:
1 parent
37d9e8ca56
commit
b76111dfc3
11 files changed
+437
-54
No files matched your search
+46
-11
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/base64"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
@@ -30,6 +31,12 @@ type Config struct {
|
||||
// 离线许可证 Ed25519 seed(32 字节 hex;生产必须固定,勿轮换除非同步桌面公钥) // Logan.Li
|
||||
OfflineLicenseSeed string
|
||||
|
||||
// 客户端授权防护配置 // Logan.Li
|
||||
GracePeriodDays int // 过期宽限天数(仅商业过期;吊销/暂停无宽限)
|
||||
ActivateDailyLimit int // 单序列号 24 小时内新设备激活上限(0 = 不限制)
|
||||
OnlineTTLMinutes int // 激活记录在线状态有效期(last_seen 超过即视为离线)
|
||||
DeactivateRequireToken bool // 解绑是否强制校验设备激活令牌
|
||||
|
||||
// CORS 配置
|
||||
CORSOrigins []string
|
||||
}
|
||||
@@ -42,17 +49,21 @@ func Load() *Config {
|
||||
_ = godotenv.Load("../../.env")
|
||||
|
||||
cfg := &Config{
|
||||
Port: getEnv("PORT", "9001"),
|
||||
Mode: getEnv("GIN_MODE", "debug"),
|
||||
DBDriver: getEnv("DB_DRIVER", "sqlite"),
|
||||
DBHost: getEnv("DB_HOST", "127.0.0.1"),
|
||||
DBPort: getEnv("DB_PORT", "3306"),
|
||||
DBUser: getEnv("DB_USER", "root"),
|
||||
DBPassword: getEnv("DB_PASSWORD", ""),
|
||||
DBName: getEnv("DB_NAME", "db.sqlite3"),
|
||||
JWTSecret: getEnv("JWT_SECRET", ""),
|
||||
OfflineLicenseSeed: getEnv("OFFLINE_LICENSE_SEED", ""),
|
||||
CORSOrigins: defaultCORSOrigins(),
|
||||
Port: getEnv("PORT", "9001"),
|
||||
Mode: getEnv("GIN_MODE", "debug"),
|
||||
DBDriver: getEnv("DB_DRIVER", "sqlite"),
|
||||
DBHost: getEnv("DB_HOST", "127.0.0.1"),
|
||||
DBPort: getEnv("DB_PORT", "3306"),
|
||||
DBUser: getEnv("DB_USER", "root"),
|
||||
DBPassword: getEnv("DB_PASSWORD", ""),
|
||||
DBName: getEnv("DB_NAME", "db.sqlite3"),
|
||||
JWTSecret: getEnv("JWT_SECRET", ""),
|
||||
OfflineLicenseSeed: getEnv("OFFLINE_LICENSE_SEED", ""),
|
||||
GracePeriodDays: getEnvInt("GRACE_PERIOD_DAYS", 15),
|
||||
ActivateDailyLimit: getEnvInt("ACTIVATE_DAILY_LIMIT", 5),
|
||||
OnlineTTLMinutes: getEnvInt("ONLINE_TTL_MINUTES", 11520), // 默认 8 天,适配周检节奏
|
||||
DeactivateRequireToken: getEnvBool("DEACTIVATE_REQUIRE_TOKEN", true),
|
||||
CORSOrigins: defaultCORSOrigins(),
|
||||
}
|
||||
|
||||
if raw := strings.TrimSpace(os.Getenv("CORS_ORIGINS")); raw != "" {
|
||||
@@ -122,3 +133,27 @@ func getEnv(key, defaultValue string) string {
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// getEnvInt 读取整型环境变量,不存在或非法时返回默认值 // Logan.Li
|
||||
func getEnvInt(key string, defaultValue int) int {
|
||||
if raw := strings.TrimSpace(os.Getenv(key)); raw != "" {
|
||||
if v, err := strconv.Atoi(raw); err == nil {
|
||||
return v
|
||||
}
|
||||
log.Printf("[配置] %s 不是合法整数,使用默认值 %d", key, defaultValue)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// getEnvBool 读取布尔环境变量(true/false/1/0),不存在或非法时返回默认值 // Logan.Li
|
||||
func getEnvBool(key string, defaultValue bool) bool {
|
||||
if raw := strings.TrimSpace(os.Getenv(key)); raw != "" {
|
||||
switch strings.ToLower(raw) {
|
||||
case "true", "1", "yes":
|
||||
return true
|
||||
case "false", "0", "no":
|
||||
return false
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
Reference in new issue
Block a user