package session import ( "context" "encoding/gob" "log" "net/http" "os" "github.com/gorilla/securecookie" "github.com/gorilla/sessions" ) type sessionContextKey struct{} const ( sessionCookie = "sessionKeks" dataKey = "data" ) func init() { gob.Register(sessionData{}) } type Session struct { *sessionData s *sessions.Session } type sessionData struct { UserID int32 Authenticated bool } func (s *Session) Save(w http.ResponseWriter, r *http.Request) { s.s.Values[dataKey] = *s.sessionData if err := s.s.Save(r, w); err != nil { log.Panic("Storing session: ", err) } } func (s *Session) MaxAge(maxAge int) { s.s.Options.MaxAge = maxAge } func (s *Session) Invalidate() { s.MaxAge(-1) s.Authenticated = false } func (s *Session) IsNew() bool { return s.s.IsNew } // From extracts the `Session` from the `Request`. func From(r *http.Request) Session { s := r.Context().Value(sessionContextKey{}).(*sessions.Session) s.Options.HttpOnly = true sd, ok := s.Values[dataKey].(sessionData) if !ok { sd = sessionData{} } return Session{&sd, s} } func Handler() func(next http.Handler) http.Handler { var key []byte if envKey := os.Getenv("GOSTEN_SECRET"); len(envKey) >= 32 { key = []byte(envKey) } else { key = securecookie.GenerateRandomKey(32) } sessionStore := sessions.NewCookieStore(key) return func(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { session, _ := sessionStore.Get(r, sessionCookie) ctx := context.WithValue(r.Context(), sessionContextKey{}, session) next.ServeHTTP(w, r.WithContext(ctx)) } return http.HandlerFunc(fn) } }