Files
MosisService/portal/internal/web/session.go

95 lines
2.2 KiB
Go

package web
import (
"context"
"encoding/gob"
"net/http"
"github.com/omixlab/mosis-portal/internal/database"
)
func init() {
// Register types for gob encoding (used by cookie sessions)
gob.Register(&database.Developer{})
}
// SessionMiddleware handles session-based authentication for web pages
type SessionMiddleware struct {
db *database.DB
cookieKey string
}
// NewSessionMiddleware creates a new session middleware
func NewSessionMiddleware(db *database.DB, cookieKey string) *SessionMiddleware {
return &SessionMiddleware{
db: db,
cookieKey: cookieKey,
}
}
// LoadSession loads the developer from session cookie
func (m *SessionMiddleware) LoadSession(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Try to get developer ID from session cookie
cookie, err := r.Cookie("session")
if err != nil {
next.ServeHTTP(w, r)
return
}
// Lookup developer
developer, err := m.db.GetDeveloper(r.Context(), cookie.Value)
if err != nil {
// Invalid session, clear cookie
http.SetCookie(w, &http.Cookie{
Name: "session",
Value: "",
Path: "/",
MaxAge: -1,
HttpOnly: true,
})
next.ServeHTTP(w, r)
return
}
// Add developer to context
ctx := context.WithValue(r.Context(), "developer", developer)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
// RequireSession redirects to login if not authenticated
func (m *SessionMiddleware) RequireSession(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
developer := getDeveloperFromContext(r)
if developer == nil {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
next.ServeHTTP(w, r)
})
}
// SetSession creates a session for the developer
func SetSession(w http.ResponseWriter, developerID string) {
http.SetCookie(w, &http.Cookie{
Name: "session",
Value: developerID,
Path: "/",
MaxAge: 60 * 60 * 24 * 30, // 30 days
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
})
}
// ClearSession clears the session cookie
func ClearSession(w http.ResponseWriter) {
http.SetCookie(w, &http.Cookie{
Name: "session",
Value: "",
Path: "/",
MaxAge: -1,
HttpOnly: true,
})
}