v2
This commit is contained in:
@@ -1,83 +1,83 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
// import (
|
||||
// "context"
|
||||
// "time"
|
||||
|
||||
"management/internal/pkg/redis"
|
||||
)
|
||||
// "management/internal/pkg/redis"
|
||||
// )
|
||||
|
||||
var (
|
||||
storePrefix = "scs:session:"
|
||||
ctx = context.Background()
|
||||
DefaultRedisStore = newRedisStore()
|
||||
)
|
||||
// var (
|
||||
// storePrefix = "scs:session:"
|
||||
// ctx = context.Background()
|
||||
// DefaultRedisStore = newRedisStore()
|
||||
// )
|
||||
|
||||
type redisStore struct{}
|
||||
// type redisStore struct{}
|
||||
|
||||
func newRedisStore() *redisStore {
|
||||
return &redisStore{}
|
||||
}
|
||||
// func newRedisStore() *redisStore {
|
||||
// return &redisStore{}
|
||||
// }
|
||||
|
||||
// Delete should remove the session token and corresponding data from the
|
||||
// session store. If the token does not exist then Delete should be a no-op
|
||||
// and return nil (not an error).
|
||||
func (s *redisStore) Delete(token string) error {
|
||||
return redis.Del(ctx, storePrefix+token)
|
||||
}
|
||||
// // Delete should remove the session token and corresponding data from the
|
||||
// // session store. If the token does not exist then Delete should be a no-op
|
||||
// // and return nil (not an error).
|
||||
// func (s *redisStore) Delete(token string) error {
|
||||
// return redis.Del(ctx, storePrefix+token)
|
||||
// }
|
||||
|
||||
// Find should return the data for a session token from the store. If the
|
||||
// session token is not found or is expired, the found return value should
|
||||
// be false (and the err return value should be nil). Similarly, tampered
|
||||
// or malformed tokens should result in a found return value of false and a
|
||||
// nil err value. The err return value should be used for system errors only.
|
||||
func (s *redisStore) Find(token string) (b []byte, found bool, err error) {
|
||||
val, err := redis.GetBytes(ctx, storePrefix+token)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
} else {
|
||||
return val, true, nil
|
||||
}
|
||||
}
|
||||
// // Find should return the data for a session token from the store. If the
|
||||
// // session token is not found or is expired, the found return value should
|
||||
// // be false (and the err return value should be nil). Similarly, tampered
|
||||
// // or malformed tokens should result in a found return value of false and a
|
||||
// // nil err value. The err return value should be used for system errors only.
|
||||
// func (s *redisStore) Find(token string) (b []byte, found bool, err error) {
|
||||
// val, err := redis.GetBytes(ctx, storePrefix+token)
|
||||
// if err != nil {
|
||||
// return nil, false, err
|
||||
// } else {
|
||||
// return val, true, nil
|
||||
// }
|
||||
// }
|
||||
|
||||
// Commit should add the session token and data to the store, with the given
|
||||
// expiry time. If the session token already exists, then the data and
|
||||
// expiry time should be overwritten.
|
||||
func (s *redisStore) Commit(token string, b []byte, expiry time.Time) error {
|
||||
// TODO: 这边可以调整时间
|
||||
exp, err := time.ParseInLocation(time.DateTime, time.Now().Format("2006-01-02")+" 23:59:59", time.Local)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// // Commit should add the session token and data to the store, with the given
|
||||
// // expiry time. If the session token already exists, then the data and
|
||||
// // expiry time should be overwritten.
|
||||
// func (s *redisStore) Commit(token string, b []byte, expiry time.Time) error {
|
||||
// // TODO: 这边可以调整时间
|
||||
// exp, err := time.ParseInLocation(time.DateTime, time.Now().Format("2006-01-02")+" 23:59:59", time.Local)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
t := time.Now()
|
||||
expired := exp.Sub(t)
|
||||
return redis.Set(ctx, storePrefix+token, b, expired)
|
||||
}
|
||||
// t := time.Now()
|
||||
// expired := exp.Sub(t)
|
||||
// return redis.Set(ctx, storePrefix+token, b, expired)
|
||||
// }
|
||||
|
||||
// All should return a map containing data for all active sessions (i.e.
|
||||
// sessions which have not expired). The map key should be the session
|
||||
// token and the map value should be the session data. If no active
|
||||
// sessions exist this should return an empty (not nil) map.
|
||||
func (s *redisStore) All() (map[string][]byte, error) {
|
||||
sessions := make(map[string][]byte)
|
||||
// // All should return a map containing data for all active sessions (i.e.
|
||||
// // sessions which have not expired). The map key should be the session
|
||||
// // token and the map value should be the session data. If no active
|
||||
// // sessions exist this should return an empty (not nil) map.
|
||||
// func (s *redisStore) All() (map[string][]byte, error) {
|
||||
// sessions := make(map[string][]byte)
|
||||
|
||||
iter := redis.Scan(ctx, 0, storePrefix+"*", 0).Iterator()
|
||||
for iter.Next(ctx) {
|
||||
key := iter.Val()
|
||||
token := key[len(storePrefix):]
|
||||
data, exists, err := s.Find(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// iter := redis.Scan(ctx, 0, storePrefix+"*", 0).Iterator()
|
||||
// for iter.Next(ctx) {
|
||||
// key := iter.Val()
|
||||
// token := key[len(storePrefix):]
|
||||
// data, exists, err := s.Find(token)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
if exists {
|
||||
sessions[token] = data
|
||||
}
|
||||
}
|
||||
if err := iter.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// if exists {
|
||||
// sessions[token] = data
|
||||
// }
|
||||
// }
|
||||
// if err := iter.Err(); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
return sessions, nil
|
||||
}
|
||||
// return sessions, nil
|
||||
// }
|
||||
|
||||
@@ -5,55 +5,68 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"management/internal/config"
|
||||
db "management/internal/db/sqlc"
|
||||
|
||||
"github.com/alexedwards/scs/pgxstore"
|
||||
"github.com/alexedwards/scs/v2"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
var sessionManager *scs.SessionManager
|
||||
type ISession interface {
|
||||
Destroy(ctx context.Context) error
|
||||
LoadAndSave(next http.Handler) http.Handler
|
||||
Put(ctx context.Context, key string, val any)
|
||||
GetBytes(ctx context.Context, key string) []byte
|
||||
Exists(ctx context.Context, key string) bool
|
||||
RenewToken(ctx context.Context) error
|
||||
}
|
||||
|
||||
func Init() {
|
||||
sessionManager = scs.New()
|
||||
type session struct {
|
||||
sessionManager *scs.SessionManager
|
||||
}
|
||||
|
||||
func New(pool *pgxpool.Pool, prod bool) ISession {
|
||||
sessionManager := scs.New()
|
||||
sessionManager.Lifetime = 24 * time.Hour
|
||||
sessionManager.IdleTimeout = 2 * time.Hour
|
||||
sessionManager.Cookie.Name = "token"
|
||||
sessionManager.Cookie.HttpOnly = true
|
||||
sessionManager.Cookie.Persist = true
|
||||
sessionManager.Cookie.SameSite = http.SameSiteStrictMode
|
||||
sessionManager.Cookie.Secure = config.File.App.Prod
|
||||
sessionManager.Cookie.Secure = prod
|
||||
|
||||
// postgres
|
||||
// github.com/alexedwards/scs/postgresstore
|
||||
// sessionManager.Store = postgresstore.New(db)
|
||||
// pgx
|
||||
// github.com/alexedwards/scs/pgxstore
|
||||
sessionManager.Store = pgxstore.New(db.Engine.Pool())
|
||||
sessionManager.Store = pgxstore.New(pool)
|
||||
// redis
|
||||
// sessionManager.Store = newRedisStore()
|
||||
|
||||
return &session{
|
||||
sessionManager: sessionManager,
|
||||
}
|
||||
}
|
||||
|
||||
func Destroy(ctx context.Context) error {
|
||||
return sessionManager.Destroy(ctx)
|
||||
func (s *session) Destroy(ctx context.Context) error {
|
||||
return s.sessionManager.Destroy(ctx)
|
||||
}
|
||||
|
||||
func LoadAndSave(next http.Handler) http.Handler {
|
||||
return sessionManager.LoadAndSave(next)
|
||||
func (s *session) LoadAndSave(next http.Handler) http.Handler {
|
||||
return s.sessionManager.LoadAndSave(next)
|
||||
}
|
||||
|
||||
func Put(ctx context.Context, key string, val interface{}) {
|
||||
sessionManager.Put(ctx, key, val)
|
||||
func (s *session) Put(ctx context.Context, key string, val any) {
|
||||
s.sessionManager.Put(ctx, key, val)
|
||||
}
|
||||
|
||||
func GetBytes(ctx context.Context, key string) []byte {
|
||||
return sessionManager.GetBytes(ctx, key)
|
||||
func (s *session) GetBytes(ctx context.Context, key string) []byte {
|
||||
return s.sessionManager.GetBytes(ctx, key)
|
||||
}
|
||||
|
||||
func Exists(ctx context.Context, key string) bool {
|
||||
return sessionManager.Exists(ctx, key)
|
||||
func (s *session) Exists(ctx context.Context, key string) bool {
|
||||
return s.sessionManager.Exists(ctx, key)
|
||||
}
|
||||
|
||||
func RenewToken(ctx context.Context) error {
|
||||
return sessionManager.RenewToken(ctx)
|
||||
func (s *session) RenewToken(ctx context.Context) error {
|
||||
return s.sessionManager.RenewToken(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user