加入首次使用的引导页、写入readme文件

This commit is contained in:
2026-07-23 22:17:48 +08:00
parent 892fc98be2
commit 55fb5d49f7
11 changed files with 766 additions and 1828 deletions
+19 -21
View File
@@ -13,12 +13,18 @@ import (
"golang.org/x/crypto/bcrypt"
)
var jwtSecretCache []byte
func getJwtSecret() []byte {
if len(jwtSecretCache) > 0 {
return jwtSecretCache
}
secret, err := GetJwtSecret()
if err != nil {
log.Fatal("❌ 获取 JWT 密钥失败:", err)
}
return []byte(secret)
jwtSecretCache = []byte(secret)
return jwtSecretCache
}
type Claims struct {
@@ -51,49 +57,45 @@ func ParseJWT(tokenString string) (*Claims, error) {
return nil, errors.New("invalid token")
}
// 密码复杂度验证:至少8位密码,包含大写字母、数字和特殊字符
func ValidatePassword(pwd string) bool {
if len(pwd) < 8 {
return false
}
var hasLetter, hasDigit bool
var hasUpper, hasLower, hasDigit, hasSpecial bool
for _, ch := range pwd {
if (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') {
hasLetter = true
}
if ch >= '0' && ch <= '9' {
if ch >= 'A' && ch <= 'Z' {
hasUpper = true
} else if ch >= 'a' && ch <= 'z' {
hasLower = true
} else if ch >= '0' && ch <= '9' {
hasDigit = true
} else if strings.ContainsAny(string(ch), "!@#$%^&*()_+-=[]{}|;:,.<>?") {
hasSpecial = true
}
}
return hasLetter && hasDigit
return hasUpper && hasLower && hasDigit && hasSpecial
}
// 首次启动强制设置管理员账户
func InitAdminUser() {
count, err := CountUsers()
if err != nil {
log.Fatal("❌ 检查用户表失败:", err)
}
if count > 0 {
log.Println("✅ 已存在管理员账户,跳过初始化")
return
}
log.Println("⚠️ 首次启动,请设置管理员账户")
log.Print("用户名: ")
var username string
fmt.Scanln(&username)
if username == "" {
username = "admin"
}
for {
log.Print("密码 (至少8位密码,包含大写字母、数字特殊字符): ")
log.Print("密码 (至少8位,含大小写、数字特殊字符): ")
var password string
fmt.Scanln(&password)
if ValidatePassword(password) {
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
@@ -109,12 +111,11 @@ func InitAdminUser() {
break
} else {
log.Println("❌ 密码不符合复杂度要求,请重新输入")
log.Println(" 要求: 至少8位密码,包含大写字母、数字和特殊字符")
log.Println(" 要求: 至少8位,包含大写字母、数字和特殊字符")
}
}
}
// JWT 认证中间件
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
@@ -123,21 +124,18 @@ func AuthMiddleware() gin.HandlerFunc {
c.Abort()
return
}
// 格式 "Bearer <token>"
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
c.JSON(http.StatusUnauthorized, gin.H{"code": 1, "msg": "认证令牌格式错误"})
c.Abort()
return
}
tokenString := parts[1]
claims, err := ParseJWT(tokenString)
claims, err := ParseJWT(parts[1])
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"code": 1, "msg": "无效的认证令牌"})
c.Abort()
return
}
// 将用户名存入上下文,方便后续使用
c.Set("username", claims.Username)
c.Next()
}