From 423a4acca98f2efa60145b752c805aa7d5e11983 Mon Sep 17 00:00:00 2001 From: Mathieu Coulet Date: Mon, 2 Dec 2024 10:54:01 +0100 Subject: [PATCH] feat(Server): argon2 auth --- server/internal/controllers/auth.go | 12 ++++++++++-- server/internal/models/users.go | 1 + server/internal/utils/auth.go | 28 ++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/server/internal/controllers/auth.go b/server/internal/controllers/auth.go index f88565b..0677e5c 100644 --- a/server/internal/controllers/auth.go +++ b/server/internal/controllers/auth.go @@ -24,11 +24,16 @@ func Login(c *gin.Context) { email := c.PostForm("email") password := c.PostForm("password") var user models.User - db.DB.Where("email = ? AND password = ?", email, password).First(&user) + db.DB.Where("email = ?", email).First(&user) if user.ID == 0 { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"}) return } + if err := utils.VerifyPassword(password, user.Password, user.Salt); err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"}) + return + } + tokenString := utils.NewToken(c, email) db.DB.Model(&user).Update("token", tokenString) c.JSON(http.StatusOK, gin.H{"token": tokenString}) @@ -52,9 +57,12 @@ func Register(c *gin.Context) { c.JSON(http.StatusConflict, gin.H{"error": "User already exists"}) return } + password, salt := utils.HashPassword(c.PostForm("password")) + db.DB.Create(&models.User{ Email: c.PostForm("email"), - Password: c.PostForm("password"), + Password: password, + Salt: salt, Token: tokenString, }) c.JSON(http.StatusOK, gin.H{"token": tokenString}) diff --git a/server/internal/models/users.go b/server/internal/models/users.go index 4a217c3..e363fac 100644 --- a/server/internal/models/users.go +++ b/server/internal/models/users.go @@ -8,5 +8,6 @@ type User struct { gorm.Model Email string `gorm:"unique;not null" json:"email" binding:"required"` Password string `gorm:"not null" json:"password" binding:"required"` + Salt string `gorm:"not null" json:"salt"` Token string `gorm:"not null" json:"token"` } diff --git a/server/internal/utils/auth.go b/server/internal/utils/auth.go index c1f87fe..4850808 100644 --- a/server/internal/utils/auth.go +++ b/server/internal/utils/auth.go @@ -1,12 +1,32 @@ package utils import ( + "crypto/rand" "encoding/base64" + "errors" "golang.org/x/crypto/argon2" + "log" ) -func HashPassword(password string) string { - salt := []byte("randomSalt") - hash := argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) - return base64.RawStdEncoding.EncodeToString(hash) +func VerifyPassword(password, hashedPassword, salt string) error { + hash := argon2.IDKey([]byte(password), []byte(salt), 1, 64*1024, 4, 32) + if base64.RawStdEncoding.EncodeToString(hash) != hashedPassword { + return errors.New("invalid password") + } + return nil +} + +func randomSalt() string { + salt := make([]byte, 16) + _, err := rand.Read(salt) + if err != nil { + log.Fatalf("Error occurred while generating random salt: %v", err) + } + return base64.RawStdEncoding.EncodeToString(salt) +} + +func HashPassword(password string) (string, string) { + salt := randomSalt() + hash := argon2.IDKey([]byte(password), []byte(salt), 1, 64*1024, 4, 32) + return base64.RawStdEncoding.EncodeToString(hash), salt }