84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"management/internal/pkg/redis"
|
|
)
|
|
|
|
var (
|
|
storePrefix = "scs:session:"
|
|
ctx = context.Background()
|
|
DefaultRedisStore = newRedisStore()
|
|
)
|
|
|
|
type redisStore struct{}
|
|
|
|
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)
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
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)
|
|
|
|
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
|
|
}
|
|
|
|
return sessions, nil
|
|
}
|