first commit
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Session represents a user session
|
||||
type Session struct {
|
||||
ID string
|
||||
UserID uint
|
||||
Username string
|
||||
CreatedAt time.Time
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
// SessionManager manages user sessions
|
||||
type SessionManager struct {
|
||||
sessions map[string]*Session
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewSessionManager creates a new session manager
|
||||
func NewSessionManager() *SessionManager {
|
||||
return &SessionManager{
|
||||
sessions: make(map[string]*Session),
|
||||
}
|
||||
}
|
||||
|
||||
// generateSessionID generates a random session ID
|
||||
func generateSessionID() string {
|
||||
bytes := make([]byte, 32)
|
||||
rand.Read(bytes)
|
||||
return hex.EncodeToString(bytes)
|
||||
}
|
||||
|
||||
// CreateSession creates a new session for a user
|
||||
func (sm *SessionManager) CreateSession(userID int, username string) *Session {
|
||||
sm.mutex.Lock()
|
||||
defer sm.mutex.Unlock()
|
||||
|
||||
// Clean up expired sessions
|
||||
sm.cleanupExpiredSessions()
|
||||
|
||||
sessionID := generateSessionID()
|
||||
session := &Session{
|
||||
ID: sessionID,
|
||||
UserID: uint(userID),
|
||||
Username: username,
|
||||
CreatedAt: time.Now(),
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour), // 24 hours
|
||||
}
|
||||
|
||||
sm.sessions[sessionID] = session
|
||||
return session
|
||||
}
|
||||
|
||||
// GetSession retrieves a session by ID
|
||||
func (sm *SessionManager) GetSession(sessionID string) (*Session, bool) {
|
||||
sm.mutex.RLock()
|
||||
defer sm.mutex.RUnlock()
|
||||
|
||||
session, exists := sm.sessions[sessionID]
|
||||
if !exists {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Check if session is expired
|
||||
if time.Now().After(session.ExpiresAt) {
|
||||
delete(sm.sessions, sessionID)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return session, true
|
||||
}
|
||||
|
||||
// DeleteSession deletes a session
|
||||
func (sm *SessionManager) DeleteSession(sessionID string) {
|
||||
sm.mutex.Lock()
|
||||
defer sm.mutex.Unlock()
|
||||
|
||||
delete(sm.sessions, sessionID)
|
||||
}
|
||||
|
||||
// cleanupExpiredSessions removes expired sessions
|
||||
func (sm *SessionManager) cleanupExpiredSessions() {
|
||||
now := time.Now()
|
||||
for id, session := range sm.sessions {
|
||||
if now.After(session.ExpiresAt) {
|
||||
delete(sm.sessions, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetSessionCookie sets a session cookie
|
||||
func SetSessionCookie(w http.ResponseWriter, sessionID string) {
|
||||
cookie := &http.Cookie{
|
||||
Name: "session_id",
|
||||
Value: sessionID,
|
||||
Expires: time.Now().Add(24 * time.Hour),
|
||||
HttpOnly: true,
|
||||
Secure: false, // Set to true in production with HTTPS
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
Path: "/",
|
||||
}
|
||||
http.SetCookie(w, cookie)
|
||||
}
|
||||
|
||||
// GetSessionCookie gets the session ID from cookie
|
||||
func GetSessionCookie(r *http.Request) (string, error) {
|
||||
cookie, err := r.Cookie("session_id")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return cookie.Value, nil
|
||||
}
|
||||
|
||||
// ClearSessionCookie clears the session cookie
|
||||
func ClearSessionCookie(w http.ResponseWriter) {
|
||||
cookie := &http.Cookie{
|
||||
Name: "session_id",
|
||||
Value: "",
|
||||
Expires: time.Unix(0, 0),
|
||||
HttpOnly: true,
|
||||
Secure: false, // Set to true in production with HTTPS
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
Path: "/",
|
||||
}
|
||||
http.SetCookie(w, cookie)
|
||||
}
|
||||
Reference in New Issue
Block a user