【问题标题】:How to Compare Hashed Passwords in Golang?如何比较 Golang 中的哈希密码?
【发布时间】:2022-01-24 14:27:29
【问题描述】:

我试图在 Golang 的 Fiber Farmework 上构建登录系统,并使用 Mysql 作为数据库。 我可以轻松地散列我的密码,但无法比较给定密码和存储的密码是否相同 我用过

bcrypt.CompareHashAndPassword() 方法..虽然我给出了完全相同的密码,但它仍然给出了一个错误。 请帮帮我

功能

   func hashAndSalt(password string) string {
    pwd := []byte(password)
    hash, err := bcrypt.GenerateFromPassword(pwd, 14)
    if err != nil {
        log.Println(err)
    }
    return string(hash)
}
func CheckHash(hpass string, pass string) error {
    err := bcrypt.CompareHashAndPassword([]byte(hpass), []byte(pass))
    if err != nil {
        return err
    }
    return nil
}

用户和登录类型

type User struct {
    gorm.Model
    FirstName string `json:"firstname"`
    LastName  string `json:"lastname"`
    Username  string `json:"username"`
    Password  string `json:"-"`
    UserType  string `json:"user_type"`
}
type Log struct {
        Username string `json:"username"`
        Password string `json:"password"`
    }

创建用户功能很好用

func CreateUser(c *fiber.Ctx) error {
    user := new(User)
    if err := c.BodyParser(user); err != nil {
        return c.Status(500).SendString(err.Error())
    }
    pass := user.Password
    hashedPass := hashAndSalt(pass)
    user.Password = hashedPass
    DB.Create(&user)
    return c.JSON(&user)
}

登录方法...问题在于哈希检查...

const jwt_secret = "Fahim'sAwesomeSecret"

func Login(c *fiber.Ctx) error {
    type Log struct {
        Username string `json:"username"`
        Password string `json:"password"`
    }
    var body Log
    if err := c.BodyParser(&body); err != nil {
        fmt.Println(err.Error(), "yayy")
        panic(err.Error())
    }

    username := body.Username
    password := body.Password
    var user User
    DB.Where("username = ?", username).First(&user)
    if username != user.Username {
        return c.Status(200).SendString("User not Found , Maybe wrong Username")
    }

    err := CheckHash(user.Password, password)
    if err != nil {
        fmt.Println(err)
        return c.Status(500).SendString("Wrong Password")
    }

    token := jwt.New(jwt.SigningMethodHS256)
    claims := token.Claims.(jwt.MapClaims)

    claims["sub"] = user.ID
    claims["exp"] = time.Now().Add(time.Hour * 24 * 7)
    s, err := token.SignedString([]byte(jwt_secret))
    if err != nil {
        return c.SendStatus(fiber.StatusInternalServerError)
    }
    c.Cookie(&fiber.Cookie{
        Name:     "jwt",
        Value:    s,
        Expires:  time.Now().Add(7 * 24 * time.Hour),
        HTTPOnly: true,
        SameSite: "lax",
    })

    return c.Status(fiber.StatusOK).JSON(fiber.Map{
        "token": s,
        "user":  user,
    })
}

这是我在终端中遇到的错误

crypto/bcrypt: hashedPassword is not the hash of the given password

我已经打印了“user.Password”,并给出了存储在数据库中的值。 那么问题出在哪里?

【问题讨论】:

  • 这是一个关于 Fiber 的问题(如果是,请询问 Fiber 的作者),关于如何使用包 bcrypt(这看起来很合理),还是您希望进行代码审查?
  • 将其记入minimal reproducible example 将有助于获得答案,尽管这样做可能会为您解答问题。
  • 在您的数据库中,您将哈希存储为字符串,但您得到的是 [] 字节。在CheckHash 中,您只是将字符串转换为 []byte,但不以任何方式对其进行解码。如果您在存储期间的某个地方对其进行 base64 编码,那么您应该正确解码它,而不是仅仅将编码的字符串转换为字节
  • @caveman 我是否必须使用变量并执行类似的操作?" newVar := []byte(hpass)" 然后在函数中使用该变量?我试过了,但没有用,你能给我举个你刚才说的话的例子吗?
  • @caveman 我按照你说的过程解决了

标签: go hash bcrypt fibers go-fiber


【解决方案1】:

我通过更改 User 结构解决了这个问题 Passwordstringbyte

并据此进行一些更改

【讨论】:

    猜你喜欢
    • 2023-03-29
    • 2019-11-11
    • 2016-09-29
    • 2017-09-19
    • 2016-09-13
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    • 2021-09-27
    相关资源
    最近更新 更多