Golang中的正则表达式使用指南

Golang中的正则表达式使用指南 大家好,

我正在开发一个验证用户密码更新的函数。

我需要用这个正则表达式来加强密码安全性:

?=^.{8,}$)(?=.\d)(?=.[a-z])(?=.[A-Z])(?!.\s)[0-9a-zA-Z!@#$%^&()]*$

但我不知道如何在代码中实现它。

这是我的代码:

// UpdatePassword  uptdate the password for this user.
  func UpdatePassword(unitID string, loginID string, password string) (err error) {
f := GetFederation(unitID)
ldap := connections[f.Connection]
hash, err := HashPassword(password, "SSHA", nil)
if err != nil {
    msg := fmt.Sprintf("password hash generation failed for %s. Error: %s", loginID, err.Error())
    return errors.New(msg)
}
originalPasswordHash, err := mdb.GetUserPasswordHash(loginID, f.ID)
if err != nil {
    if err.Error() == mgo.ErrNotFound.Error() & ldap != nil {
        var profile map[string]string
        profile, err = ldap.GetProfile(loginID)
        if err != nil {
            debug.Println("get Profile error ", err)
            return err
        }
        login := profile[config.Connections[f.ID].LoginField]
        loginID, originalPasswordHash, err = ldap.GetPasswordHash(login)
        if err != nil {
            return err
        }
    } else {
        return err
    }
}
if err = mdb.ChangeUserPassword(loginID, f.ID, hash); err != nil {
    debug.Println("ChangeUserPassword error ", err)
    return err
}

if ldap != nil {
    err = ldap.ChangePassword(loginID, password)
    if err != nil {
        info.Printf("revert password change in DB for user %s", loginID)
        if err = mdb.ChangeUserPassword(loginID, f.ID, originalPasswordHash); err != nil {
            return fmt.Errorf("cannot revert password for user %s in DB", loginID)
        }
        return fmt.Errorf("cannot change password for user %s in ldap", loginID)
    }
}

return nil

大家有什么想法吗?

非常感谢


更多关于Golang中的正则表达式使用指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

问题是给定的正则表达式被论坛破坏了,因为原帖作者没有使用反引号将其包裹起来。

更多关于Golang中的正则表达式使用指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你尝试过使用正则表达式包吗? https://golang.org/pkg/regexp/

是的,我正在处理这个问题。

但我不确定如何在我的函数中实现这个功能,

您有可以在我的函数中实现的示例吗?谢谢

PS:我是初学者

你的正则表达式无法编译通过

matched, err := regexp.MatchString(`foo.*`, "seafood")
fmt.Println(matched, err)

一个简单的示例。建议在修改密码功能之前先运行这段代码并检查错误。

在Go语言中,可以使用regexp包来实现正则表达式验证。你的正则表达式旨在验证密码必须包含至少8个字符,至少一个数字、一个小写字母、一个大写字母,不能包含空格,并且允许特定特殊字符。以下是具体实现方法:

首先,修正你的正则表达式。原始表达式在Go中可能无法直接使用,因为它包含正向先行断言(?=),而Go的regexp包不支持这种语法。你需要将其转换为Go兼容的形式。一个替代方案是分别检查各个条件。

以下是修改后的代码示例,在密码更新函数中加入正则验证:

import (
    "errors"
    "fmt"
    "regexp"
    "unicode"
)

// validatePassword 使用正则表达式和额外检查验证密码强度
func validatePassword(password string) error {
    // 检查长度至少8个字符
    if len(password) < 8 {
        return errors.New("password must be at least 8 characters long")
    }

    // 检查是否包含数字
    hasDigit := false
    // 检查是否包含小写字母
    hasLower := false
    // 检查是否包含大写字母
    hasUpper := false
    // 检查是否包含空格
    hasSpace := false
    // 定义允许的特殊字符集
    allowedSpecial := "!@#$%^&*()"

    for _, char := range password {
        switch {
        case unicode.IsDigit(char):
            hasDigit = true
        case unicode.IsLower(char):
            hasLower = true
        case unicode.IsUpper(char):
            hasUpper = true
        case unicode.IsSpace(char):
            hasSpace = true
        default:
            // 检查是否为允许的特殊字符
            allowed := false
            for _, special := range allowedSpecial {
                if char == special {
                    allowed = true
                    break
                }
            }
            if !allowed {
                return errors.New("password contains invalid characters")
            }
        }
    }

    if !hasDigit {
        return errors.New("password must contain at least one digit")
    }
    if !hasLower {
        return errors.New("password must contain at least one lowercase letter")
    }
    if !hasUpper {
        return errors.New("password must contain at least one uppercase letter")
    }
    if hasSpace {
        return errors.New("password must not contain spaces")
    }

    return nil
}

// UpdatePassword 更新用户密码,包括密码强度验证
func UpdatePassword(unitID string, loginID string, password string) (err error) {
    // 首先验证密码
    if err := validatePassword(password); err != nil {
        return fmt.Errorf("password validation failed: %v", err)
    }

    f := GetFederation(unitID)
    ldap := connections[f.Connection]
    hash, err := HashPassword(password, "SSHA", nil)
    if err != nil {
        msg := fmt.Sprintf("password hash generation failed for %s. Error: %s", loginID, err.Error())
        return errors.New(msg)
    }
    originalPasswordHash, err := mdb.GetUserPasswordHash(loginID, f.ID)
    if err != nil {
        if err.Error() == mgo.ErrNotFound.Error() && ldap != nil {
            var profile map[string]string
            profile, err = ldap.GetProfile(loginID)
            if err != nil {
                debug.Println("get Profile error ", err)
                return err
            }
            login := profile[config.Connections[f.ID].LoginField]
            loginID, originalPasswordHash, err = ldap.GetPasswordHash(login)
            if err != nil {
                return err
            }
        } else {
            return err
        }
    }
    if err = mdb.ChangeUserPassword(loginID, f.ID, hash); err != nil {
        debug.Println("ChangeUserPassword error ", err)
        return err
    }

    if ldap != nil {
        err = ldap.ChangePassword(loginID, password)
        if err != nil {
            info.Printf("revert password change in DB for user %s", loginID)
            if err = mdb.ChangeUserPassword(loginID, f.ID, originalPasswordHash); err != nil {
                return fmt.Errorf("cannot revert password for user %s in DB", loginID)
            }
            return fmt.Errorf("cannot change password for user %s in ldap", loginID)
        }
    }

    return nil
}

如果你坚持使用正则表达式,可以尝试以下简化版本,但请注意它可能无法完全覆盖所有条件,因为Go的regexp不支持先行断言:

import "regexp"

// 简化版正则验证(不包含先行断言)
func validatePasswordWithRegex(password string) error {
    // 这个正则检查:至少8个字符,只允许数字、字母和特定特殊字符
    pattern := `^[0-9a-zA-Z!@#$%^&*()]{8,}$`
    matched, err := regexp.MatchString(pattern, password)
    if err != nil {
        return err
    }
    if !matched {
        return errors.New("password does not meet the required pattern")
    }
    return nil
}

在实际应用中,推荐使用第一种方法(validatePassword函数),因为它更清晰地检查每个条件,并提供了具体的错误消息。在UpdatePassword函数开始处调用验证函数,确保密码符合安全要求后再继续执行后续操作。

回到顶部