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

Опубликовано: 28 Февраль 2025
на канале: Maharlikans Code
179
12

In this Golang Web Development Series #33, 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
#GolangWebDevelopment33
#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/settings.go:
package yabi

import (
"strings"
"sync"
)
const YabiCookieName = "yabi"
var ExpireCookieInDays int = 30 // number of days
type InitYabi struct {
BaseURL string // e.g http://127.0.0.1:8081/ or https://maharlikanscode.com/ with the trailing "/" slash
mu sync.Mutex // ensures atomic writes; protect the following fields
}

// YB is the pointer for InitYabi configuration
var YB *InitYabi

// InitYabiConfig initialize all the necessary yabi configurations and its default values
func InitYabiConfig(b *InitYabi) *InitYabi {
// Check all the required configurations are in place or not
if len(strings.TrimSpace(b.BaseURL)) == 0 {
b.BaseURL = "http://127.0.0.1:8081/"
}
return &InitYabi{
BaseURL: b.BaseURL,
}
}

func init() {
// Set initial default yabi config
YB = InitYabiConfig(&InitYabi{})
}

// SetYabiConfig sets the custom config values from the user
func SetYabiConfig(b *InitYabi) *InitYabi {
b.mu.Lock()
defer b.mu.Unlock()

// Check all the required configurations are in place or not
if len(strings.TrimSpace(b.BaseURL)) == 0 {
b.BaseURL = "http://127.0.0.1:8081/"
}

// Re-configure the yabi configurations
b = InitYabiConfig(b)
return b
}
main.go:
package main

...

func main() {
...
// Default is development settings
webServerIP := "127.0.0.1:8081" // default to dev localhost

// Initialize the Yabi auth API here
yabiBaseURL := "http://" + webServerIP + "/" // default to dev localhost
if IsProdServerMode {
yabiBaseURL = config.SiteBaseURLProd
}
yabi.SetYabiConfig(&yabi.InitYabi{BaseURL: yabiBaseURL})
...
}
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"
"github.com/itrepablik/timaan"
)
func LoginUser(dbCon *sql.DB, u User, isSiteKeepMe bool, expireInDays int) (bool, error) {
pwHash, err := GetUserPassword(dbCon, u.UserName)
if err != nil {
return false, errors.New("Oops!, error getting user's credential, please try again")
}
isPassHashMatch, err := sakto.CheckPasswordHash(u.Password, pwHash)
if err != nil {
return false, errors.New("Oops!, either of your username or password is wrong, please try again, thank you")
}

if isPassHashMatch {
mUser := GetUserInfo(dbCon, u.UserName)
tokenPayload := timaan.TP{
"USER_ID": fmt.Sprint(mUser.ID),
"USERNAME": fmt.Sprint(mUser.UserName),
"EMAIL": fmt.Sprint(mUser.Email),
"FIRST_NAME": fmt.Sprint(mUser.FirstName),
"MIDDLE_NAME": fmt.Sprint(mUser.MiddleName),
"LAST_NAME": fmt.Sprint(mUser.LastName),
"SUFFIX": fmt.Sprint(mUser.Suffix),
"IS_SUPER_USER": fmt.Sprint(mUser.IsSuperUser),
"IS_ADMIN": fmt.Sprint(mUser.IsAdmin),
"LAST_LOGIN": fmt.Sprint(mUser.LastLogin),
"DATE_JOINED": fmt.Sprint(mUser.DateJoined),
}
if expireInDays lt 1 {
expireInDays = ExpireCookieInDays
}
var tokenExpiry int64 = time.Now().Add(time.Minute * 30).Unix()
if isSiteKeepMe {
tokenExpiry = time.Now().Add(time.Hour * time.Duration(24*expireInDays)).Unix()
}
tok := timaan.TK{
TokenKey: mUser.UserName,
Payload: tokenPayload,
ExpireOn: tokenExpiry,
}
_, err = timaan.GenerateToken(mUser.UserName, tok)
if err != nil {
itrlog.Error("error generating token during login: ", err)
return false, errors.New("Oops!, there was an error during encoding process, please try again, thank you")
}
LastLogin(dbCon, mUser.UserName)
return true, nil
}
return false, errors.New("Invalid Credentials, either of your username or password is wrong, please try again, thank you")
}
...
func LastLogin(dbCon *sql.DB, userName string) {
upd, err := dbCon.Prepare("UPDATE " + YabiUser + " SET last_login = ? WHERE username = ? AND is_active = ?")
if err != nil {
itrlog.Error("ERROR FROM LastLogin: ", err)
}
upd.Exec(time.Now(), userName, true)
defer upd.Close()
}
Get the full source codes:
https://github.com/maharlikanscode/Go...