fix(gateway): 三处生产安全硬化(默认密钥/admin裸奔/CORS)
1) JWT 默认密钥:生产模式(APP_ENV=production|prod 或 GIN_MODE=release)下若未设 JWT_SECRET 直接 log.Fatal,杜绝用开发默认值签发可伪造令牌;开发期警告并放行。 2) /admin 运维控制面(含模型 API 密钥管理)改挂 RequireAdmin:必须登录 + (设了 ADMIN_USER_IDS 则)uid 须在白名单;生产期未配置管理员直接 403。 3) CORS Allow-Origin 由 CORS_ALLOW_ORIGIN 配置(缺省 * 仅开发),非 * 时加 Vary。 build + auth 单测通过。仍属"小范围灰度"级,TLS/可观测/集成测试/HA 见 PROGRESS。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,9 @@ package auth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
@@ -13,8 +15,28 @@ import (
|
||||
// TokenTTL 是访问令牌有效期。
|
||||
const TokenTTL = 24 * time.Hour
|
||||
|
||||
// secret 是 JWT 签名密钥。生产经环境变量 JWT_SECRET 注入;缺省仅供开发(务必覆盖)。
|
||||
var secret = []byte(envOr("JWT_SECRET", "sundynix-dev-secret-change-me"))
|
||||
const devSecret = "sundynix-dev-secret-change-me"
|
||||
|
||||
// secret 是 JWT 签名密钥。生产必须经 JWT_SECRET 注入强密钥;
|
||||
// 生产模式(APP_ENV=production/prod 或 GIN_MODE=release)下未设则直接 fatal,杜绝可伪造令牌。
|
||||
var secret = []byte(resolveSecret())
|
||||
|
||||
func resolveSecret() string {
|
||||
if s := os.Getenv("JWT_SECRET"); s != "" {
|
||||
return s
|
||||
}
|
||||
if isProd() {
|
||||
log.Fatal("[auth] 生产模式必须设置 JWT_SECRET(强随机密钥),拒绝使用开发默认值")
|
||||
}
|
||||
log.Println("[auth] ⚠️ 使用开发默认 JWT 密钥,生产务必设置 JWT_SECRET")
|
||||
return devSecret
|
||||
}
|
||||
|
||||
// isProd 判定是否生产环境。
|
||||
func isProd() bool {
|
||||
env := strings.ToLower(os.Getenv("APP_ENV"))
|
||||
return env == "production" || env == "prod" || strings.ToLower(os.Getenv("GIN_MODE")) == "release"
|
||||
}
|
||||
|
||||
// ErrInvalidToken 表示令牌无效/过期/签名不符。
|
||||
var ErrInvalidToken = errors.New("invalid token")
|
||||
|
||||
Reference in New Issue
Block a user