Hello!
I’m trying to verify if the user entered valid credentials, so far, I’m storing the hashed password in my users table along with other fields (I’m using Gorm).
The problem comes when I try to validate the password as I’m not sure how to approach it, my first thought was receiving JSON and decoding it into my User structure, then, find an user with the ID provided (instead of say, email - as of now) and store it in another variable of type User, then use bcrypt.CompareHashAndPassword
to compare the passwords but it’s returning nil
(valid match) every single time even if the passwords are not the same.
Here is my handler:
func Login(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
db := utils.InitDB()
defer db.Close()
// This is the "user" that comes along with the POST request
var user models.User
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&user)
if err != nil {
utils.ErrorWithJSON(w, "Invalid data", http.StatusBadRequest)
return
}
// This is the user found in the database with the ID provided in the POST request
var u2 models.User
id := user.ID
db.First(&u2, id)
if u2.ID == 0 {
utils.ErrorWithJSON(w, "User not found", http.StatusNotFound)
return
}
err = bcrypt.CompareHashAndPassword([]byte(u2.Password), []byte(user.Password))
if err != nil {
log.Fatal("WRONG PASSWORD")
return
}
log.Println("CORRECT PASSWORD")
}
A POST request would be similar to (as of now).
{
"id": 2,
"name": "Andres",
"password": "123456"
}
I’m pretty sure my approach is not the correct one, so I would like to know why is it failing and what would be a better way to do it?
Thank you so much for your time!
EDIT
The problem was that I had my Password field being ignored in the structure
type User struct {
ID uint `gorm:"primary_key" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `json:"deleted_at,omitempty"`
Name string `gorm:"type:varchar(100); not null" json:"name"`
Username string `gorm:"type:varchar(30); unique_index; not null" json:"username"`
Email string `gorm:"type:varchar(100); unique_index; not null" json:"email"`
Country string `gorm:"type:varchar(30); not null" json:"country,omitempty"`
Password string `gorm:"type:varchar(255); not null" json:"-"`
CohortID uint `json:"cohort_id,omitempty"`
}
It works correctly now, however, I do not want to send my Password in future GET requests, how could I avoid this then?
Any suggestions to improve the code would be super appreciated, once again, thanks for your time.