Implement sensitive word filtering feature with configurable database and Redis support. Add security enhancements including WebSocket origin validation, improved password strength requirements, timing attack prevention, and production JWT secret validation. Add batch operation validation limits and optimize user blocking queries with subqueries. BREAKING CHANGE: Password validation now requires minimum 8 characters with uppercase, lowercase, and digit (was 6-50 characters without complexity requirements)
97 lines
2.2 KiB
Go
97 lines
2.2 KiB
Go
package utils
|
||
|
||
import (
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
// ValidateEmail 验证邮箱
|
||
func ValidateEmail(email string) bool {
|
||
pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
|
||
matched, _ := regexp.MatchString(pattern, email)
|
||
return matched
|
||
}
|
||
|
||
// ValidateUsername 验证用户名
|
||
func ValidateUsername(username string) bool {
|
||
if len(username) < 3 || len(username) > 30 {
|
||
return false
|
||
}
|
||
pattern := `^[a-zA-Z0-9_]+$`
|
||
matched, _ := regexp.MatchString(pattern, username)
|
||
return matched
|
||
}
|
||
|
||
// ValidatePassword 验证密码强度
|
||
func ValidatePassword(password string) bool {
|
||
if len(password) < 8 || len(password) > 50 {
|
||
return false
|
||
}
|
||
|
||
var hasUpper, hasLower, hasDigit bool
|
||
for _, c := range password {
|
||
switch {
|
||
case 'A' <= c && c <= 'Z':
|
||
hasUpper = true
|
||
case 'a' <= c && c <= 'z':
|
||
hasLower = true
|
||
case '0' <= c && c <= '9':
|
||
hasDigit = true
|
||
}
|
||
}
|
||
|
||
return hasUpper && hasLower && hasDigit
|
||
}
|
||
|
||
// ValidatePasswordWithDetail 验证密码强度并返回详细信息
|
||
func ValidatePasswordWithDetail(password string) (bool, string) {
|
||
if len(password) < 8 {
|
||
return false, "密码长度至少8位"
|
||
}
|
||
if len(password) > 50 {
|
||
return false, "密码长度不能超过50位"
|
||
}
|
||
|
||
var hasUpper, hasLower, hasDigit bool
|
||
for _, c := range password {
|
||
switch {
|
||
case 'A' <= c && c <= 'Z':
|
||
hasUpper = true
|
||
case 'a' <= c && c <= 'z':
|
||
hasLower = true
|
||
case '0' <= c && c <= '9':
|
||
hasDigit = true
|
||
}
|
||
}
|
||
|
||
if !hasUpper {
|
||
return false, "密码必须包含大写字母"
|
||
}
|
||
if !hasLower {
|
||
return false, "密码必须包含小写字母"
|
||
}
|
||
if !hasDigit {
|
||
return false, "密码必须包含数字"
|
||
}
|
||
|
||
return true, ""
|
||
}
|
||
|
||
// ValidatePhone 验证手机号
|
||
func ValidatePhone(phone string) bool {
|
||
pattern := `^1[3-9]\d{9}$`
|
||
matched, _ := regexp.MatchString(pattern, phone)
|
||
return matched
|
||
}
|
||
|
||
// SanitizeHTML 清理HTML,防止XSS攻击
|
||
func SanitizeHTML(input string) string {
|
||
input = strings.ReplaceAll(input, "&", "&")
|
||
input = strings.ReplaceAll(input, "<", "<")
|
||
input = strings.ReplaceAll(input, ">", ">")
|
||
input = strings.ReplaceAll(input, "\"", """)
|
||
input = strings.ReplaceAll(input, "'", "'")
|
||
input = strings.ReplaceAll(input, "/", "/")
|
||
return input
|
||
}
|