first commit
This commit is contained in:
75
services/session_service.go
Normal file
75
services/session_service.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SessionService 인메모리 세션 스토어
|
||||
type SessionService struct {
|
||||
sessions sync.Map // sessionID → time.Time(만료시각)
|
||||
ttl time.Duration // 세션 유효 기간
|
||||
}
|
||||
|
||||
var sessionServiceInstance *SessionService
|
||||
var sessionServiceOnce sync.Once
|
||||
|
||||
// GetSessionService 세션 서비스 싱글톤 반환
|
||||
func GetSessionService() *SessionService {
|
||||
sessionServiceOnce.Do(func() {
|
||||
sessionServiceInstance = NewSessionService()
|
||||
})
|
||||
return sessionServiceInstance
|
||||
}
|
||||
|
||||
// NewSessionService 세션 서비스 초기화 (TTL 24시간)
|
||||
func NewSessionService() *SessionService {
|
||||
svc := &SessionService{ttl: 24 * time.Hour}
|
||||
go svc.cleanup()
|
||||
return svc
|
||||
}
|
||||
|
||||
// Create 새 세션 생성 → sessionID(UUID) 반환
|
||||
func (s *SessionService) Create() string {
|
||||
b := make([]byte, 16)
|
||||
_, _ = rand.Read(b)
|
||||
id := hex.EncodeToString(b)
|
||||
s.sessions.Store(id, time.Now().Add(s.ttl))
|
||||
return id
|
||||
}
|
||||
|
||||
// Validate 세션 유효성 검사 (만료 시 자동 삭제)
|
||||
func (s *SessionService) Validate(id string) bool {
|
||||
val, ok := s.sessions.Load(id)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
expiry, ok := val.(time.Time)
|
||||
if !ok || time.Now().After(expiry) {
|
||||
s.sessions.Delete(id)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Delete 세션 삭제 (로그아웃)
|
||||
func (s *SessionService) Delete(id string) {
|
||||
s.sessions.Delete(id)
|
||||
}
|
||||
|
||||
// cleanup 만료된 세션을 주기적으로 정리 (1시간 주기)
|
||||
func (s *SessionService) cleanup() {
|
||||
ticker := time.NewTicker(time.Hour)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
now := time.Now()
|
||||
s.sessions.Range(func(key, val any) bool {
|
||||
if expiry, ok := val.(time.Time); ok && now.After(expiry) {
|
||||
s.sessions.Delete(key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user