140 lines
3.3 KiB
Go
140 lines
3.3 KiB
Go
|
|
package sanitizer
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"strings"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// SensitiveFields 敏感字段列表
|
|||
|
|
var SensitiveFields = []string{
|
|||
|
|
"password", " Password", "pwd",
|
|||
|
|
"token", "access_token", "refresh_token", "Token",
|
|||
|
|
"secret", "Secret", "api_key", "apiKey", "secret_key",
|
|||
|
|
"id_card", "idCard", "身份证",
|
|||
|
|
"phone", "mobile", "Phone", "Mobile", "手机号",
|
|||
|
|
"email", "Email", "邮箱",
|
|||
|
|
"bank_card", "bankCard", "银行卡",
|
|||
|
|
"credit_card", "信用卡",
|
|||
|
|
"address", "Address", "详细地址",
|
|||
|
|
"real_name", "realName", "真实姓名",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// SkipMaskFields 不需要脱敏的字段
|
|||
|
|
var SkipMaskFields = []string{
|
|||
|
|
"avatar", "nickname", "username", "content", "title", "description",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// MaskValue 根据字段名脱敏处理
|
|||
|
|
func MaskValue(field, value string) string {
|
|||
|
|
if value == "" {
|
|||
|
|
return ""
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fieldLower := strings.ToLower(field)
|
|||
|
|
|
|||
|
|
// 检查是否跳过脱敏
|
|||
|
|
for _, f := range SkipMaskFields {
|
|||
|
|
if fieldLower == f || strings.HasSuffix(fieldLower, f) {
|
|||
|
|
return value
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据字段类型脱敏
|
|||
|
|
switch {
|
|||
|
|
case strings.Contains(fieldLower, "phone"):
|
|||
|
|
return maskPhone(value)
|
|||
|
|
case strings.Contains(fieldLower, "email"):
|
|||
|
|
return maskEmail(value)
|
|||
|
|
case strings.Contains(fieldLower, "id_card"):
|
|||
|
|
return maskIDCard(value)
|
|||
|
|
case strings.Contains(fieldLower, "bank_card") || strings.Contains(fieldLower, "credit_card"):
|
|||
|
|
return maskBankCard(value)
|
|||
|
|
case strings.Contains(fieldLower, "token") || strings.Contains(fieldLower, "secret") || strings.Contains(fieldLower, "api_key"):
|
|||
|
|
return "***"
|
|||
|
|
case fieldLower == "password" || fieldLower == "pwd":
|
|||
|
|
return "***"
|
|||
|
|
case strings.Contains(fieldLower, "address"):
|
|||
|
|
return maskAddress(value)
|
|||
|
|
case strings.Contains(fieldLower, "real_name"):
|
|||
|
|
return maskName(value)
|
|||
|
|
default:
|
|||
|
|
return value
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// maskPhone 手机号脱敏(保留前3后4)
|
|||
|
|
func maskPhone(s string) string {
|
|||
|
|
if len(s) == 11 {
|
|||
|
|
return s[:3] + "****" + s[7:]
|
|||
|
|
}
|
|||
|
|
return "***"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// maskEmail 邮箱脱敏(保留前2)
|
|||
|
|
func maskEmail(s string) string {
|
|||
|
|
parts := strings.Split(s, "@")
|
|||
|
|
if len(parts) == 2 && len(parts[0]) > 2 {
|
|||
|
|
return parts[0][:2] + "***@" + parts[1]
|
|||
|
|
}
|
|||
|
|
return "***"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// maskIDCard 身份证脱敏(保留前6后4)
|
|||
|
|
func maskIDCard(s string) string {
|
|||
|
|
if len(s) == 18 {
|
|||
|
|
return s[:6] + "********" + s[14:]
|
|||
|
|
}
|
|||
|
|
if len(s) == 15 {
|
|||
|
|
return s[:6] + "*****" + s[11:]
|
|||
|
|
}
|
|||
|
|
return "***"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// maskBankCard 银行卡号脱敏(保留前4后4)
|
|||
|
|
func maskBankCard(s string) string {
|
|||
|
|
length := len(s)
|
|||
|
|
if length >= 8 {
|
|||
|
|
return s[:4] + "****" + s[length-4:]
|
|||
|
|
}
|
|||
|
|
return "***"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// maskAddress 地址脱敏(只显示省市)
|
|||
|
|
func maskAddress(s string) string {
|
|||
|
|
parts := strings.Split(s, "省")
|
|||
|
|
if len(parts) > 1 {
|
|||
|
|
cityParts := strings.Split(parts[1], "市")
|
|||
|
|
if len(cityParts) > 1 {
|
|||
|
|
return parts[0] + "省" + cityParts[0] + "市****"
|
|||
|
|
}
|
|||
|
|
return parts[0] + "省****"
|
|||
|
|
}
|
|||
|
|
return "***"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// maskName 姓名脱敏(保留姓氏)
|
|||
|
|
func maskName(s string) string {
|
|||
|
|
runes := []rune(s)
|
|||
|
|
length := len(runes)
|
|||
|
|
if length == 0 {
|
|||
|
|
return ""
|
|||
|
|
}
|
|||
|
|
if length == 2 {
|
|||
|
|
return string(runes[0]) + "*"
|
|||
|
|
}
|
|||
|
|
if length >= 3 {
|
|||
|
|
return string(runes[0]) + "*" + string(runes[length-1:])
|
|||
|
|
}
|
|||
|
|
return "*"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IsSensitiveField 判断字段是否为敏感字段
|
|||
|
|
func IsSensitiveField(field string) bool {
|
|||
|
|
fieldLower := strings.ToLower(field)
|
|||
|
|
for _, f := range SensitiveFields {
|
|||
|
|
if strings.Contains(fieldLower, f) {
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false
|
|||
|
|
}
|