package session import ( "context" "encoding/json" "errors" "net/http" "time" "management/internal/erpserver/model/dto" "management/internal/pkg/config" "github.com/alexedwards/scs/postgresstore" "github.com/alexedwards/scs/v2" "gorm.io/gorm" ) var ErrNoSession = errors.New("session user not found") // Manager 抽象核心会话操作 type Manager interface { Load(next http.Handler) http.Handler GetUser(ctx context.Context, key string) (*dto.AuthorizeUser, error) PutUser(ctx context.Context, key string, user *dto.AuthorizeUser) error RenewToken(ctx context.Context) error Destroy(ctx context.Context) error } type SCSSession struct { manager *scs.SessionManager } func NewSCSManager(db *gorm.DB, config *config.Config) (Manager, error) { 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.App.Prod sqlDB, err := db.DB() if err != nil { return nil, err } // postgres // github.com/alexedwards/scs/postgresstore sessionManager.Store = postgresstore.New(sqlDB) // pgx // github.com/alexedwards/scs/pgxstore // sessionManager.Store = pgxstore.New(pool) // redis // sessionManager.Store = newRedisStore() return &SCSSession{manager: sessionManager}, nil } func (s *SCSSession) Load(next http.Handler) http.Handler { return s.manager.LoadAndSave(next) } func (s *SCSSession) GetUser(ctx context.Context, key string) (*dto.AuthorizeUser, error) { data, ok := s.manager.Get(ctx, key).([]byte) if !ok || len(data) == 0 { return nil, ErrNoSession } var user dto.AuthorizeUser if err := json.Unmarshal(data, &user); err != nil { return nil, err } return &user, nil } func (s *SCSSession) PutUser(ctx context.Context, key string, user *dto.AuthorizeUser) error { data, err := json.Marshal(user) if err != nil { return err } s.manager.Put(ctx, key, data) return nil } func (s *SCSSession) RenewToken(ctx context.Context) error { return s.manager.RenewToken(ctx) } func (s *SCSSession) Destroy(ctx context.Context) error { return s.manager.Destroy(ctx) }