feat: 优化web
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"giter.top/smart/pkg/config"
|
||||
"giter.top/smart/pkg/security"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
// ErrInvalidSession 会话不存在或已过期。
|
||||
var ErrInvalidSession = errors.New("session: invalid or expired")
|
||||
|
||||
const redisKeyPrefix = "auth:sess:"
|
||||
|
||||
type payload struct {
|
||||
UserID string `json:"user_id"`
|
||||
TenantID string `json:"tenant_id"`
|
||||
}
|
||||
|
||||
// Store Redis 会话(供 OAuth authorize 与登出)。
|
||||
type Store struct {
|
||||
rdb redis.UniversalClient
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
// NewStore 创建会话存储。
|
||||
func NewStore(rdb redis.UniversalClient, cfg *config.Config) *Store {
|
||||
return &Store{rdb: rdb, cfg: cfg}
|
||||
}
|
||||
|
||||
func (s *Store) ttl() time.Duration {
|
||||
t := s.cfg.Auth.Session.TTL
|
||||
if t == 0 {
|
||||
return 168 * time.Hour
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Create 创建会话并返回 session id(写入 Cookie 用)。
|
||||
func (s *Store) Create(ctx context.Context, userID, tenantID string) (sid string, err error) {
|
||||
sid, err = security.RandomURLSafe(32)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b, err := json.Marshal(payload{UserID: userID, TenantID: tenantID})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sid, s.rdb.Set(ctx, redisKeyPrefix+sid, b, s.ttl()).Err()
|
||||
}
|
||||
|
||||
// Get 解析会话。
|
||||
func (s *Store) Get(ctx context.Context, sid string) (userID, tenantID string, err error) {
|
||||
b, err := s.rdb.Get(ctx, redisKeyPrefix+sid).Bytes()
|
||||
if err == redis.Nil {
|
||||
return "", "", ErrInvalidSession
|
||||
}
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
var p payload
|
||||
if err := json.Unmarshal(b, &p); err != nil {
|
||||
return "", "", ErrInvalidSession
|
||||
}
|
||||
return p.UserID, p.TenantID, nil
|
||||
}
|
||||
|
||||
// Delete 登出时删除。
|
||||
func (s *Store) Delete(ctx context.Context, sid string) error {
|
||||
return s.rdb.Del(ctx, redisKeyPrefix+sid).Err()
|
||||
}
|
||||
Reference in New Issue
Block a user