package middleware import ( "context" "net/http" "go.neonxp.ru/middleware/session" "go.neonxp.ru/objectid" ) type SessionConfig struct { SessionCookie string Path string Domain string Secure bool HttpOnly bool MaxAge int } type SessionManager struct { SessionID string Storer session.Store MaxAge int } func (s *SessionManager) Load(ctx context.Context) session.Value { return s.Storer.Load(ctx, s.SessionID) } func (s *SessionManager) Save(ctx context.Context, value session.Value) error { return s.Storer.Save(ctx, s.SessionID, value) } func (s *SessionManager) SetMaxAge(maxAge int) { s.MaxAge = maxAge } func Session(config *SessionConfig, storer session.Store) Middleware { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { sessionID := objectid.New().String() cookie, err := r.Cookie(config.SessionCookie) if err == nil { sessionID = cookie.Value } sessionManager := &SessionManager{SessionID: sessionID, Storer: storer, MaxAge: config.MaxAge} h.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), sessionKey, &sessionManager))) http.SetCookie(w, &http.Cookie{ Name: config.SessionCookie, Value: sessionID, Path: config.Path, Domain: config.Domain, Secure: config.Secure, HttpOnly: config.HttpOnly, MaxAge: sessionManager.MaxAge, }) }) } } func SessionFromRequest(r *http.Request) *SessionManager { return r.Context().Value(sessionKey).(*SessionManager) }