mirror of
https://github.com/serty2005/rmser.git
synced 2026-02-04 19:02:33 -06:00
0302-добавил куки и сломал десктоп авторизацию.
сложно поддерживать однояйцевых близнецов - desktop и TMA, подготовил к рефакторингу структуры
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"rmser/internal/domain/account"
|
||||
@@ -22,9 +25,9 @@ type Claims struct {
|
||||
|
||||
// Service представляет сервис авторизации для desktop auth
|
||||
type Service struct {
|
||||
accountRepo account.Repository
|
||||
wsServer *ws.Server
|
||||
secretKey string
|
||||
accountRepo account.Repository
|
||||
wsServer *ws.Server
|
||||
secretKey string
|
||||
}
|
||||
|
||||
// NewService создает новый экземпляр сервиса авторизации
|
||||
@@ -105,3 +108,76 @@ func (s *Service) generateJWTToken(user *account.User) (string, error) {
|
||||
|
||||
return tokenString, nil
|
||||
}
|
||||
|
||||
// generateRefreshToken генерирует безопасный refresh токен
|
||||
func (s *Service) generateRefreshToken() (string, error) {
|
||||
b := make([]byte, 32)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
// CreateWebSession создает новую веб-сессию для пользователя
|
||||
func (s *Service) CreateWebSession(userID uuid.UUID, userAgent, ip string) (*account.Session, error) {
|
||||
token, err := s.generateRefreshToken()
|
||||
if err != nil {
|
||||
logger.Log.Error("failed to generate refresh token", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
session := &account.Session{
|
||||
UserID: userID,
|
||||
RefreshToken: token,
|
||||
UserAgent: userAgent,
|
||||
IP: ip,
|
||||
ExpiresAt: time.Now().Add(7 * 24 * time.Hour),
|
||||
}
|
||||
|
||||
if err := s.accountRepo.CreateSession(session); err != nil {
|
||||
logger.Log.Error("failed to create session", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// ValidateAndExtendSession проверяет и продлевает сессию (sliding window)
|
||||
func (s *Service) ValidateAndExtendSession(token string) (*account.User, error) {
|
||||
session, err := s.accountRepo.GetSessionByToken(token)
|
||||
if err != nil {
|
||||
logger.Log.Error("failed to get session", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if session == nil {
|
||||
return nil, fmt.Errorf("session not found")
|
||||
}
|
||||
|
||||
if time.Now().After(session.ExpiresAt) {
|
||||
// Сессия истекла, удаляем её
|
||||
s.accountRepo.DeleteSession(token)
|
||||
return nil, fmt.Errorf("session expired")
|
||||
}
|
||||
|
||||
// Sliding expiration: обновляем expiresAt на 7 дней от текущего момента
|
||||
newExpiry := time.Now().Add(7 * 24 * time.Hour)
|
||||
if err := s.accountRepo.UpdateSessionExpiry(session.ID, newExpiry); err != nil {
|
||||
logger.Log.Error("failed to update session expiry", zap.Error(err))
|
||||
// Не критичная ошибка, продолжаем
|
||||
}
|
||||
|
||||
// Получаем пользователя
|
||||
user, err := s.accountRepo.GetUserByID(session.UserID)
|
||||
if err != nil {
|
||||
logger.Log.Error("failed to get user", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// DeleteSession удаляет сессию пользователя
|
||||
func (s *Service) DeleteSession(token string) error {
|
||||
return s.accountRepo.DeleteSession(token)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user