Golang HTTP User Authentication Yabi Series 8 | Golang Web Development | WebAssembly Auth System

Опубликовано: 05 Октябрь 2024
на канале: Maharlikans Code
298
14

In this Golang Web Development Series #28, we're building a complete Golang HTTP User Authentication System from scratch with the backend MySQL database by using Golang's official MySQL Database Driver. The Golang HTTP Authentication will consist of Golang User Registration, Golang Login Auth, Golang Password Reset, Golang Change Password, Golang Set Cookie, Golang Web Assembly (WASM), Golang Map Token, Golang Persisted Token, etc. with step by step guide here in Golang's Web Development Series.

#MaharlikansCode
#GolangWebDevelopment28
#GolangUserAuthenticationSystem
#MySQLDatabase
#YabiSeries8
#GolangWASM
#GolangWebAssembly
#GolangTutorial
#LearnGolangWebDevelopment
#Golang
#LifeAsSoftwareDeveloper
#Maharlikans
#FilipinoSoftwareDeveloper

Get Linode Account:
https://www.linode.com/?r=6aae17162e9...

If you go with extra mile for buying me a cup of coffee, I appreciate it guys: https://ko-fi.com/maharlikanscode

Source Codes:
auth.go:
...
// ActivateAccount is to activate the new user's registration directly from the user's email address
func ActivateAccount(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles(config.SiteRootTemplate+"front/account_activation_complete.html",
config.SiteHeaderTemplateCommon, config.SiteFooterAccountTemplateCommon))

params := mux.Vars(r)
token := params["token"]

// Extract the timaan payload
tok, err := timaan.DecodePayload(token)
if err != nil {
itrlog.Error(err)
}

userName := ""
payLoad := tok.Payload
for field, val := range payLoad {
itrlog.Info("timaan token payload ", field, ": ", val)
if strings.TrimSpace(field) == "USERNAME" {
userName = fmt.Sprintf("%v", val) // Get the username value
}
}
fmt.Println("userName: ", userName)
if len(strings.TrimSpace(userName)) == 0 {
PageNotFound(w, r)
}

// Check the timaan token expiry
if time.Now().Unix() gt tok.ExpireOn {
itrlog.Warn("timaan token has been expired for username: ", userName, " : ", +time.Now().Unix(), " gt ", tok.ExpireOn)
PageNotFound(w, r)
}

// Open the MySQL DB Connection
dbYabi, err := sql.Open("mysql", DBConStr(""))
if err != nil {
itrlog.Error(err)
}
defer dbYabi.Close()

// Now, activate the user's new account which is the "is_active=true" status.
isActive := yabi.ActivateUser(dbYabi, userName)
if isActive {
data := contextData{
"PageTitle": "Your new " + config.SiteShortName + " account has been activated",
"PageMetaDesc": "Your newly created " + config.SiteShortName + " account has been successfully activated",
"CanonicalURL": r.RequestURI,
"CsrfToken": csrf.Token(r),
"Settings": config.SiteSettings,
}
tmpl.Execute(w, data)
} else {
PageNotFound(w, r)
}
}
...
user.go:
...
func CreateUser(dbCon *sql.DB, u User, e EmailConfig, confirmPassword string, tos bool) (int64, error) {
hsPassword, err := sakto.HashAndSalt([]byte(u.Password))
if err != nil {
return 0, err
}
ins, err := dbCon.Prepare("INSERT INTO " + YabiUser + " (username, password, email, first_name, " +
"middle_name, last_name, suffix, is_superuser, is_admin, date_joined, is_active) VALUES" +
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")

if err != nil {
return 0, err
}
ins.Exec(u.UserName, hsPassword, u.Email, u.FirstName, u.MiddleName, u.LastName, u.Suffix, u.IsSuperUser,
u.IsAdmin, time.Now(), u.IsActive)

lid, err := GetLastInsertedID(dbCon, "id", YabiUser)
defer ins.Close()
return lid, nil
}

func GetLastInsertedID(dbCon *sql.DB, autoIDFieldName, tableName string) (int64, error) {
var id int64 = 0
err := dbCon.QueryRow("SELECT " + autoIDFieldName + " FROM " + tableName + " ORDER BY " + autoIDFieldName + " DESC LIMIT 1").Scan(&id)
if err != nil {
return 0, err
}
return id, nil
}

func IsUserNameExist(dbCon *sql.DB, userName string) bool {
var id int64 = 0
err := dbCon.QueryRow("SELECT id FROM "+YabiUser+" WHERE username = ?", userName).Scan(&id)
if err != nil {
if err == sql.ErrNoRows {
return true
}
return false
}
return false
}

func IsUserEmailExist(dbCon *sql.DB, email string) bool {
var id int64 = 0
err := dbCon.QueryRow("SELECT id FROM "+YabiUser+" WHERE email = ?", email).Scan(&id)
if err != nil {
if err == sql.ErrNoRows {
return true
}
return false
}
return false
}

func ActivateUser(dbCon *sql.DB, userName string) bool {
upd, err := dbCon.Prepare("UPDATE " + YabiUser + " SET is_active = ? WHERE username = ?")
if err != nil {
itrlog.Error("ERROR FROM ActivateUser: ", err)
return false
}
upd.Exec(true, userName)
defer upd.Close()
return true
}
...

Get the full source codes:
https://github.com/maharlikanscode/Go...