mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
feat: use bcrypt with salts instead of md5 for hashing password (resolve #21)
This commit is contained in:
parent
625994d1e9
commit
08675bd99f
@ -5,5 +5,6 @@ WAKAPI_DB_USER=myuser
|
|||||||
WAKAPI_DB_PASSWORD=shhh
|
WAKAPI_DB_PASSWORD=shhh
|
||||||
WAKAPI_DB_HOST=localhost
|
WAKAPI_DB_HOST=localhost
|
||||||
WAKAPI_DB_PORT=3306
|
WAKAPI_DB_PORT=3306
|
||||||
|
WAKAPI_PASSWORD_SALT=shhh
|
||||||
WAKAPI_DEFAULT_USER_NAME=admin
|
WAKAPI_DEFAULT_USER_NAME=admin
|
||||||
WAKAPI_DEFAULT_USER_PASSWORD=admin # CHANGE!
|
WAKAPI_DEFAULT_USER_PASSWORD=admin123 # CHANGE!
|
@ -4,7 +4,7 @@ port = 3000
|
|||||||
base_path = /
|
base_path = /
|
||||||
|
|
||||||
[app]
|
[app]
|
||||||
cleanup = true
|
cleanup = false
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
max_connections = 2
|
max_connections = 2
|
||||||
|
1
go.mod
1
go.mod
@ -16,5 +16,6 @@ require (
|
|||||||
github.com/rubenv/sql-migrate v0.0.0-20200402132117-435005d389bc
|
github.com/rubenv/sql-migrate v0.0.0-20200402132117-435005d389bc
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
github.com/t-tiger/gorm-bulk-insert v0.0.0-20191014134946-beb77b81825f
|
github.com/t-tiger/gorm-bulk-insert v0.0.0-20191014134946-beb77b81825f
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
|
||||||
gopkg.in/ini.v1 v1.50.0
|
gopkg.in/ini.v1 v1.50.0
|
||||||
)
|
)
|
||||||
|
@ -101,7 +101,7 @@ func (m *AuthenticateMiddleware) tryGetUserByCookie(r *http.Request) (*models.Us
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !utils.CheckPassword(user, login.Password) {
|
if !utils.CheckPassword(user, login.Password, m.config.PasswordSalt) {
|
||||||
return nil, errors.New("invalid password")
|
return nil, errors.New("invalid password")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,6 +30,7 @@ type Config struct {
|
|||||||
CleanUp bool
|
CleanUp bool
|
||||||
DefaultUserName string
|
DefaultUserName string
|
||||||
DefaultUserPassword string
|
DefaultUserPassword string
|
||||||
|
PasswordSalt string
|
||||||
SecureCookieHashKey string
|
SecureCookieHashKey string
|
||||||
SecureCookieBlockKey string
|
SecureCookieBlockKey string
|
||||||
CustomLanguages map[string]string
|
CustomLanguages map[string]string
|
||||||
@ -86,6 +87,7 @@ func readConfig() *Config {
|
|||||||
dbHost := LookupFatal("WAKAPI_DB_HOST")
|
dbHost := LookupFatal("WAKAPI_DB_HOST")
|
||||||
dbName := LookupFatal("WAKAPI_DB_NAME")
|
dbName := LookupFatal("WAKAPI_DB_NAME")
|
||||||
dbPortStr := LookupFatal("WAKAPI_DB_PORT")
|
dbPortStr := LookupFatal("WAKAPI_DB_PORT")
|
||||||
|
passwordSalt := LookupFatal("WAKAPI_PASSWORD_SALT")
|
||||||
defaultUserName := LookupFatal("WAKAPI_DEFAULT_USER_NAME")
|
defaultUserName := LookupFatal("WAKAPI_DEFAULT_USER_NAME")
|
||||||
defaultUserPassword := LookupFatal("WAKAPI_DEFAULT_USER_PASSWORD")
|
defaultUserPassword := LookupFatal("WAKAPI_DEFAULT_USER_PASSWORD")
|
||||||
dbPort, err := strconv.Atoi(dbPortStr)
|
dbPort, err := strconv.Atoi(dbPortStr)
|
||||||
@ -162,6 +164,7 @@ func readConfig() *Config {
|
|||||||
DbMaxConn: dbMaxConn,
|
DbMaxConn: dbMaxConn,
|
||||||
CleanUp: cleanUp,
|
CleanUp: cleanUp,
|
||||||
SecureCookie: secureCookie,
|
SecureCookie: secureCookie,
|
||||||
|
PasswordSalt: passwordSalt,
|
||||||
DefaultUserName: defaultUserName,
|
DefaultUserName: defaultUserName,
|
||||||
DefaultUserPassword: defaultUserPassword,
|
DefaultUserPassword: defaultUserPassword,
|
||||||
CustomLanguages: customLangs,
|
CustomLanguages: customLangs,
|
||||||
|
@ -76,7 +76,7 @@ func (h *IndexHandler) Login(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.CheckPassword(user, login.Password) {
|
if !utils.CheckPassword(user, login.Password, h.config.PasswordSalt) {
|
||||||
respondAlert(w, "invalid credentials", "", "", http.StatusUnauthorized)
|
respondAlert(w, "invalid credentials", "", "", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/muety/wakapi/models"
|
"github.com/muety/wakapi/models"
|
||||||
|
"github.com/muety/wakapi/utils"
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,14 +46,14 @@ func (srv *UserService) GetAll() ([]*models.User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (srv *UserService) CreateOrGet(signup *models.Signup) (*models.User, bool, error) {
|
func (srv *UserService) CreateOrGet(signup *models.Signup) (*models.User, bool, error) {
|
||||||
pw := md5.Sum([]byte(signup.Password))
|
|
||||||
pwString := hex.EncodeToString(pw[:])
|
|
||||||
apiKey := uuid.NewV4().String()
|
|
||||||
|
|
||||||
u := &models.User{
|
u := &models.User{
|
||||||
ID: signup.Username,
|
ID: signup.Username,
|
||||||
ApiKey: apiKey,
|
ApiKey: uuid.NewV4().String(),
|
||||||
Password: pwString,
|
Password: signup.Password,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := utils.HashPassword(u, srv.Config.PasswordSalt); err != nil {
|
||||||
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := srv.Db.FirstOrCreate(u, &models.User{ID: u.ID})
|
result := srv.Db.FirstOrCreate(u, &models.User{ID: u.ID})
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/muety/wakapi/models"
|
"github.com/muety/wakapi/models"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@ -55,11 +54,16 @@ func ExtractCookieAuth(r *http.Request, config *models.Config) (login *models.Lo
|
|||||||
return login, nil
|
return login, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckPassword(user *models.User, password string) bool {
|
func CheckPassword(user *models.User, password, salt string) bool {
|
||||||
passwordHash := md5.Sum([]byte(password))
|
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password+salt))
|
||||||
passwordHashString := hex.EncodeToString(passwordHash[:])
|
return err == nil
|
||||||
if passwordHashString == user.Password {
|
}
|
||||||
return true
|
|
||||||
}
|
// inplace
|
||||||
return false
|
func HashPassword(u *models.User, salt string) error {
|
||||||
|
bytes, err := bcrypt.GenerateFromPassword([]byte(u.Password+salt), bcrypt.DefaultCost)
|
||||||
|
if err == nil {
|
||||||
|
u.Password = string(bytes)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
1.4.1
|
1.5.0
|
Loading…
Reference in New Issue
Block a user