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

Опубликовано: 01 Октябрь 2024
на канале: Maharlikans Code
169
6

In this Golang Web Development Series #29, 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
#GolangWebDevelopment29
#GolangUserAuthenticationSystem
#MySQLDatabase
#YabiSeries9
#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:
yabi/user.go:
package yabi

import (
"database/sql"
"errors"
"fmt"
"gowebapp/config"
"strings"
"time"

"github.com/itrepablik/itrlog"
"github.com/itrepablik/sakto"
"github.com/itrepablik/sulat"
)

// LoginUser validate the user's account from the use
func LoginUser(dbCon *sql.DB, u User, isSiteKeepMe bool) (bool, error) {
// Check if userName is empty
if len(strings.TrimSpace(u.UserName)) == 0 {
return false, errors.New("Username is Required")
}

// Check if password is empty
if len(strings.TrimSpace(u.Password)) == 0 {
return false, errors.New("Password is Required")
}

// Get the user's stored has password
pwHash, err := GetUserPassword(dbCon, u.UserName)
if err != nil {
itrlog.Error(err)
return false, errors.New("Oops!, error getting user's credential, please try again")
}
fmt.Println("pwHash: ", pwHash)
fmt.Println("u.Password: ", u.Password)

// Now, match the two passwords, check if it's verified or not
isPasswordMatch, err := sakto.CheckPasswordHash(u.Password, pwHash)
if err != nil {
itrlog.Error(err)
return false, errors.New("Oops!, hash password error, please try again")
}

fmt.Println("isPasswordMatch: ", isPasswordMatch)

// Get the user's stored hash password from the yabi_user table
return true, nil
}

// GetUserPassword gets the hash password stored in the yabi_user table
func GetUserPassword(dbCon *sql.DB, userName string) (string, error) {
encPassword := ""
err := dbCon.QueryRow("SELECT password FROM "+YabiUser+" WHERE username = ? AND is_active = ?", userName, "1").Scan(&encPassword)
if err != nil {
if err == sql.ErrNoRows {
return "", err // returned no rows, the email is not found from the yabi table
}
return "", err
}
return encPassword, nil
}

auth.go:
// LoginUserEndpoint is to validate the user's login credential
func LoginUserEndpoint(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", "application/json")
w.WriteHeader(http.StatusOK)

body, errBody := ioutil.ReadAll(r.Body)
if errBody != nil {
itrlog.Error(errBody)
panic(errBody.Error())
}

keyVal := make(map[string]string)
json.Unmarshal(body, &keyVal)

userName := strings.TrimSpace(keyVal["username"])
password := keyVal["password"]
isSiteKeepMe, _ := strconv.ParseBool(keyVal["isSiteKeepMe"])

fmt.Println("userName: ", userName)
fmt.Println("password: ", password)
fmt.Println("isSiteKeepMe: ", isSiteKeepMe)

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

// User's credential payload
userAccount := yabi.User{
UserName: userName,
Password: password,
}

// Check the user's login credentials
isAccountValid, err := yabi.LoginUser(dbYabi, userAccount, isSiteKeepMe)
if err != nil {
itrlog.Error(err)
w.Write([]byte(`{ "IsSuccess": "false", "AlertTitle": "User's Authentication Failed!",
"AlertMsg": "` + err.Error() + `", "AlertType": "error", "RedirectURL": "" }`))
return
}

if isAccountValid {
// Response back to the user about the succcessful user's authentication process
w.Write([]byte(`{ "IsSuccess": "true", "AlertTitle": "Login is Successful",
"AlertMsg": "You've successfully validated your ` + config.SiteShortName + `'s account",
"AlertType": "success", "RedirectURL": "http://127.0.0.1:8081/dashboard" }`))
} else {
// Failed User's Credentials
w.Write([]byte(`{ "IsSuccess": "true", "AlertTitle": "Authentication Failed",
"AlertMsg": "Login failed for user ` + userName + `, please try again",
"AlertType": "success", "RedirectURL": "" }`))
}
}

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