猿问

使用 BeforeUpdate 的 gorm 哈希密码不会使用哈希值更新密码

我有一个非常简单的User模型,我的整个模型main.go如下


package main


import (

  "fmt"


  "github.com/jinzhu/gorm"

  _ "github.com/jinzhu/gorm/dialects/mysql"

  "golang.org/x/crypto/bcrypt"

)


// User : the user data model

type User struct {

  gorm.Model


  Username string `gorm:"type:varchar(40);unique" json:"username,omitempty"`

  Password string `gorm:"size:255" json:"password,omitempty"`

}


// BeforeSave : hook before a user is saved

func (u *User) BeforeSave(scope *gorm.Scope) (err error) {

  fmt.Println("before save")

  fmt.Println(u.Password)

  if u.Password != "" {

     hash, err := MakePassword(u.Password)

     if err != nil {

        return nil

     }

     u.Password = hash

  }


  fmt.Println(u.Password)

  return

}


// MakePassword : Encrypt user password

func MakePassword(password string) (string, error) {

  bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)

  return string(bytes), err

}


func main() {

  var connectionString = fmt.Sprintf(

    "%s:%s@/%s?charset=utf8&parseTime=True&loc=Local",

    "root", "password", "project",

  )


  db, _ := gorm.Open("mysql", connectionString)

  db.AutoMigrate(&User{})

  db.Save(&User{

    Username: "name1",

    Password: "123",

  })


  db.Model(&User{

    Model: gorm.Model{ID: 1},

  }).Update(&User{

    Username: "name2",

    Password: "12345",

  })

}

我第一次创建密码并保存为哈希字符串(我注释掉了第二个更新部分并测试了它),但是当我更新它时,它被保存为纯文本。


从控制台,我可以看到Println消息,BeforeUpdate被触发,我看到它的纯密码和 MD5,但在数据库中,它被保存为纯文本。


before save

123

$2a$10$Vknv/uu7tAPRQSddPVlQ7OodIHZJmRPKktjb98U8U5.GT/OLQeQE2

before save

12345

$2a$10$K0ZkLH7slfiFmkOe5DTKr.DGNvR6HtpjxCS/1svf2ZEvfTXVkMkvu

关于如何修复它的任何想法?


BIG阳
浏览 200回答 2
2回答

米脂

根据文档,为了更改正在更新的值,您必须通过 gorm Scope 参数设置它们。在这种情况下, User 结构并不意味着用于修改。您应该改用 SetColumn。// BeforeUpdate : hook before a user is updatedfunc (u *User) BeforeUpdate(scope *gorm.Scope) (err error) {    fmt.Println("before update")    fmt.Println(u.Password)    if u.Password != "" {        hash, err := MakePassword(u.Password)        if err != nil {            return nil        }        scope.SetColumn("Password", hash)    }    fmt.Println(u.Password)    return}

一只萌萌小番薯

我认为问题是在这里你更新用户时有一个触发器,你可以在这里改变逻辑,你的密码不应该散列,希望对你有好处func (u *User) BeforeSave(scope *gorm.Scope) (err error) { fmt.Println("before save") fmt.Println(u.Password) if u.Password != "" { hash, err := MakePassword(u.Password) if err != nil {    return nil } u.Password = hash } fmt.Println(u.Password) return}
随时随地看视频慕课网APP

相关分类

Go
我要回答