Added Redis session caching

Added functions so a Redis DB could be pinged for whether the session was valid.
The session tokens also expire due to the timeout built into the Redis DB (when setting)

Signed-off-by: Ethan Wellenreiter <ewellenreiter@gmail.com>
This commit is contained in:
Ethan Wellenreiter 2025-04-04 00:16:16 -04:00
parent f718158a0c
commit 382e510a33
3 changed files with 96 additions and 15 deletions

View File

@ -1,9 +1,9 @@
redis:
address:
host: "10.0.20.46"
port:
DB:
protocol:
password:
password: "banananana"
database:
address:
port:

View File

@ -3,6 +3,7 @@ package main
import (
"fmt"
"signin"
"time"
"github.com/spf13/viper"
)
@ -41,8 +42,40 @@ func main() {
// fmt.Println(redis["address"])
err := signin.InitializeRedis(viper.GetStringMapString("redis"))
fmt.Println(err)
// fmt.Println(rs)
// fmt.Println(map[string]int{"a": 1, "b": 2, "c": 3})
if err != nil {
fmt.Println(err)
}
cookie, _ := signin.Login("monkey")
fmt.Println(cookie)
valid, err := signin.ValidateSession(cookie)
fmt.Println(valid)
if err != nil {
fmt.Println(err)
}
time.Sleep(time.Second * 10)
fmt.Println(cookie)
valid, err = signin.ValidateSession(cookie)
fmt.Println(valid)
if err != nil {
fmt.Println(err)
}
// // fmt.Println(rs)
// // fmt.Println(map[string]int{"a": 1, "b": 2, "c": 3})
// ctx := context.Background()
// err := client.Set(ctx, "test", "bar", time.Second*30).Err()
// if err != nil {
// panic(err)
// }
// val, err := client.Get(ctx, "foo").Result()
// if err != nil {
// panic(err)
// }
// fmt.Println("foo", val)
}

View File

@ -1,6 +1,9 @@
package signin
import (
"context"
"crypto/rand"
"encoding/hex"
"errors"
"strconv"
"time"
@ -10,12 +13,14 @@ import (
// implement a periodic function to clean up the redis database of old tokens
var redis_client *redis.Client = nil
var redisClient *redis.Client = nil
var ctx context.Context = nil
var SessionTime = 2 // in seconds
var TokenLength = 32
type session_data struct {
token string
username string
expiresAt time.Time
type SessionCookie struct {
token string
username string
}
type redisSettings struct {
@ -34,11 +39,13 @@ var (
func processSettingsMap(settings map[string]string, setting_struct *redisSettings) error {
for key, val := range settings {
// fmt.Println(key, val)
if val == "" {
continue
}
switch key {
case "host":
// fmt.Println("entered")
setting_struct.host = val
case "port":
s, err := strconv.ParseUint(val, 10, 16)
@ -62,15 +69,38 @@ func processSettingsMap(settings map[string]string, setting_struct *redisSetting
setting_struct.db = s
}
}
// fmt.Println(setting_struct)
return nil
}
func Login() { // add entry into
func generateSecureToken(length int) string {
b := make([]byte, length)
if _, err := rand.Read(b); err != nil {
return ""
}
return hex.EncodeToString(b)
}
func ValidateSession(token string) bool { // check if it's a valid session against the redis database
return false
func Login(username string) (cookie SessionCookie, err error) {
// generate token here
cookie.token = generateSecureToken(TokenLength)
cookie.username = username
err = redisClient.Set(ctx, cookie.username, cookie.token, time.Second*time.Duration(SessionTime)).Err()
return cookie, err
}
func ValidateSession(cookie SessionCookie) (bool, error) { // check if it's a valid session against the redis database
val, err := redisClient.Get(ctx, cookie.username).Result()
if err != nil || val != cookie.token {
if err == redis.Nil {
err = nil // override the error. Just to say it's not an error, but in fact it's not in the database
}
return false, err
}
return true, err
}
func InitializeRedis(settings map[string]string) error {
@ -90,12 +120,30 @@ func InitializeRedis(settings map[string]string) error {
}
// initializing redis connection
redis_client = redis.NewClient(&redis.Options{
redisClient = redis.NewClient(&redis.Options{
Addr: string(strconv.AppendUint([]byte(redis_setup.host+":"), uint64(redis_setup.port), 10)),
Password: redis_setup.password,
DB: int(redis_setup.db),
Protocol: int(redis_setup.protocol),
})
ctx = context.Background()
return nil
}
func ClearSessions() error {
err := redisClient.FlushDB(ctx).Err()
if err != nil {
return err
}
return nil
}
func ClearSession(username string) error {
err := redisClient.Del(ctx, username).Err()
if err != nil {
return err
}
return nil
}