Files
MonkeyCode/backend/pkg/session/session.go

90 lines
1.7 KiB
Go

package session
import (
"context"
"encoding/json"
"fmt"
"net"
"net/http"
"time"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
"github.com/redis/go-redis/v9"
"github.com/chaitin/MonkeyCode/backend/config"
)
type Session struct {
cfg *config.Config
rdb *redis.Client
}
func NewSession(cfg *config.Config) *Session {
addr := net.JoinHostPort(cfg.Redis.Host, fmt.Sprint(cfg.Redis.Port))
rdb := redis.NewClient(&redis.Options{
Addr: addr,
Password: cfg.Redis.Pass,
DB: 3,
})
return &Session{
cfg: cfg,
rdb: rdb,
}
}
func (s *Session) Save(c echo.Context, name, domain string, data any) (string, error) {
expire := time.Duration(s.cfg.Session.ExpireDay) * 24 * time.Hour
id := uuid.New().String()
b, err := json.Marshal(data)
if err != nil {
return "", err
}
if ok, err := s.rdb.SetNX(context.Background(), id, string(b), expire).Result(); !ok || err != nil {
return "", fmt.Errorf("failed to save session: %w", err)
}
c.SetCookie(&http.Cookie{
Name: name,
Value: id,
Path: "/",
Domain: domain,
MaxAge: int(s.cfg.Session.ExpireDay) * 24 * 60 * 60,
Secure: false,
HttpOnly: true,
})
return id, nil
}
func (s *Session) Del(c echo.Context, name string) error {
ck, err := c.Cookie(name)
if err != nil {
return err
}
if err := s.rdb.Del(c.Request().Context(), ck.Value).Err(); err != nil {
return err
}
ck.MaxAge = -1
c.SetCookie(ck)
return nil
}
func Get[T any](s *Session, c echo.Context, name string) (T, error) {
var t T
ck, err := c.Cookie(name)
if err != nil {
return t, err
}
ss, err := s.rdb.Get(c.Request().Context(), ck.Value).Result()
if err != nil {
return t, err
}
if err := json.Unmarshal([]byte(ss), &t); err != nil {
return t, err
}
return t, err
}