// Save adds a single session to the response. func (s *SentinelFailoverStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if session.Options.MaxAge < 0 { if err := s.delete(session); err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options)) return nil } if session.ID == "" { // Because the ID is not initialized when newly created, encode it to // use alphanumeric characters only. session.ID = strings.TrimRight( base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32)), "=") } if err := s.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
// Save saves the given session into the database and deletes cookies if needed func (db *PGStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { // Set delete if max-age is < 0 if session.Options.MaxAge < 0 { if err := db.destroy(session); err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options)) return nil } if session.ID == "" { // Generate a random session ID key suitable for storage in the DB session.ID = strings.TrimRight( base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32)), "=") } if err := db.save(session); err != nil { return err } // Keep the session ID key in a cookie so it can be looked up in DB later. encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, db.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
func (s *Store) destroy(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { options := *s.options options.MaxAge = -1 http.SetCookie(w, sessions.NewCookie(session.Name(), "", &options)) for k := range session.Values { delete(session.Values, k) } return s.q.DeleteSession(session.ID) }
func saveCookie(w http.ResponseWriter, s *sessions.Session, store *sessions.CookieStore) (string, error) { encoded, err := securecookie.EncodeMulti(s.Name(), s.Values, store.Codecs...) if err != nil { return "", err } cookie := sessions.NewCookie(s.Name(), encoded, s.Options) http.SetCookie(w, cookie) return cookie.Value, nil }
// Save adds a single session to the response. func (s *Store) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if session.Options.MaxAge < 0 { s.delete(session) http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options)) } else { // Build an alphanumeric ID. if session.ID == "" { session.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=") } if err := s.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) } return nil }
func (s *RethinkDBStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if err := s.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
// Save saves a session to the store. If the session has no ID, Save assigns // a random one. This implementation of Save never returns a non-nil error // if client is storing sessions data in a *RamSessions instance. func (s *RAMStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if session.ID == "" { session.ID = strings.TrimRight( base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32)), "=") } if err := s.save(session); err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), session.ID, session.Options)) return nil }
// Save adds a single session to the response. func (s *Store) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { // Marked for deletion if session.Options.MaxAge < 0 { s.delete(session) // Even we fail to delete, we should clear the cookie http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options)) return nil } // Build an alphanumeric session id // FYI: Session ID is protected by MAC by securecookie so it can't be forged. if session.ID == "" { session.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=") } if err := s.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
func (s *RedisStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if session.ID == "" { // Because the ID is used in the filename, encode it to // use alphanumeric characters only. session.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=") } if err := s.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
func (m *SqliteStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { var err error if session.ID == "" { if err = m.insert(session); err != nil { return err } } else if err = m.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, m.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
// Delete removes the session from redis, and sets the cookie to expire. // // WARNING: This method should be considered deprecated since it is not exposed via the gorilla/sessions interface. // Set session.Options.MaxAge = -1 and call Save instead. - July 18th, 2013 func (s *RediStore) Delete(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { conn := s.Pool.Get() defer conn.Close() if _, err := conn.Do("DEL", "session_"+session.ID); err != nil { return err } // Set cookie to expire. options := *session.Options options.MaxAge = -1 http.SetCookie(w, sessions.NewCookie(session.Name(), "", &options)) // Clear session values. for k := range session.Values { delete(session.Values, k) } return nil }
func (m *SqliteStore) Delete(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { // Set cookie to expire. options := *session.Options options.MaxAge = -1 http.SetCookie(w, sessions.NewCookie(session.Name(), "", &options)) // Clear session values. for k := range session.Values { delete(session.Values, k) } _, delErr := m.stmtDelete.Exec(session.ID) if delErr != nil { return delErr } return nil }
// Save adds a single session to the response. func (s *MemoryStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { Log.Info("MemoryStore Save()", session.ID) if session.ID == "" { session.ID = strings.TrimRight( base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32)), "=") } if err := s.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
// Save adds a single session to the response. func (s *MemcacheStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if session.ID == "" { session.ID = s.prefix + strings.TrimRight( base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32)), "=") } c := appengine.NewContext(r) if err := saveToMemcache(c, s.nonPersistentSessionDuration, session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
func TestStore_New(t *testing.T) { db, err := bolt.Open("./sessions.db", 0666, nil) if err != nil { t.Error(err) } defer db.Close() str, err := New( db, Config{}, []byte("secret-key"), ) if err != nil { t.Error(err) } req, err := http.NewRequest("GET", "http://localhost:3000/", nil) if err != nil { t.Error(err) } encoded, err := securecookie.EncodeMulti("test", "1", str.codecs...) req.AddCookie(sessions.NewCookie("test", encoded, &sessions.Options{ MaxAge: 1024, })) session, err := str.New(req, "test") if err != nil { t.Error(err) } if session.IsNew != true { t.Errorf("session.IsNew should be true (actual: %+v)", session.IsNew) } }
func TestNeo4jStore(t *testing.T) { defer Cleanup() ss, _ := NewNeo4jStore(dbUrl, []byte(secret)) if ss == nil { t.Fatal("This test requires a real database") } // ROUND 1 - Check that the cookie is being saved req, err := http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create request", err) } session, err := ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get session", err.Error()) } session.Values["counter"] = 1 m := make(http.Header) if err = ss.Save(req, headerOnlyResponseWriter(m), session); err != nil { t.Fatal("Failed to save session:", err.Error()) } if m["Set-Cookie"][0][0:6] != "mysess" { t.Fatal("Cookie wasn't set!") } // ROUND 2 - check that the cookie can be retrieved req, err = http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create round 2 request", err) } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, ss.Codecs...) if err != nil { t.Fatal("Failed to make cookie value", err) } req.AddCookie(sessions.NewCookie(session.Name(), encoded, session.Options)) session, err = ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get round 2 session", err.Error()) } if session.Values["counter"] != 1 { t.Fatal("Retrieved session had wrong value:", session.Values["counter"]) } session.Values["counter"] = 9 // set new value for round 3 if err = ss.Save(req, headerOnlyResponseWriter(m), session); err != nil { t.Fatal("Failed to save session:", err.Error()) } // ROUND 2 - check that the cookie has been updated req, err = http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create round 3 request", err) } req.AddCookie(sessions.NewCookie(session.Name(), encoded, session.Options)) session, err = ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get session round 3", err.Error()) } if session.Values["counter"] != 9 { t.Fatal("Retrieved session had wrong value in round 3:", session.Values["counter"]) } // ROUND 3 - Increase max length req, err = http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create round 3 request", err) } req.AddCookie(sessions.NewCookie(session.Name(), encoded, session.Options)) session, err = ss.New(req, "my session") session.Values["big"] = make([]byte, base64.StdEncoding.DecodedLen(4096*2)) if err = ss.Save(req, headerOnlyResponseWriter(m), session); err == nil { t.Fatal("expected an error, got nil") } ss.MaxLength(4096 * 3) // A bit more than the value size to account for encoding overhead. if err = ss.Save(req, headerOnlyResponseWriter(m), session); err != nil { t.Fatal("Failed to save session:", err.Error()) } }
func TestPGStore(t *testing.T) { ss := NewPGStore(os.Getenv("PGSTORE_TEST_CONN"), []byte(secret)) if ss == nil { t.Fatal("This test requires a real database") } defer ss.Close() // ROUND 1 - Check that the cookie is being saved req, err := http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create request", err) } session, err := ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get session", err.Error()) } session.Values["counter"] = 1 m := make(http.Header) if err = ss.Save(req, headerOnlyResponseWriter(m), session); err != nil { t.Fatal("Failed to save session:", err.Error()) } if m["Set-Cookie"][0][0:6] != "mysess" { t.Fatal("Cookie wasn't set!") } // ROUND 2 - check that the cookie can be retrieved req, err = http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create round 2 request", err) } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, ss.Codecs...) if err != nil { t.Fatal("Failed to make cookie value", err) } req.AddCookie(sessions.NewCookie(session.Name(), encoded, session.Options)) session, err = ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get round 2 session", err.Error()) } if session.Values["counter"] != 1 { t.Fatal("Retrieved session had wrong value:", session.Values["counter"]) } session.Values["counter"] = 9 // set new value for round 3 if err = ss.Save(req, headerOnlyResponseWriter(m), session); err != nil { t.Fatal("Failed to save session:", err.Error()) } // ROUND 2 - check that the cookie has been updated req, err = http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create round 3 request", err) } req.AddCookie(sessions.NewCookie(session.Name(), encoded, session.Options)) session, err = ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get session round 3", err.Error()) } if session.Values["counter"] != 9 { t.Fatal("Retrieved session had wrong value in round 3:", session.Values["counter"]) } }
func TestPGStore(t *testing.T) { ss := New() if ss == nil { t.Fatal("This test requires a real database") } // ROUND 1 - Check that the cookie is being saved req, err := http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create request", err) } session, err := ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get session", err.Error()) } session.Values["counter"] = 1 m := make(http.Header) if err = ss.Save(req, headerOnlyResponseWriter(m), session); err != nil { t.Fatal("Failed to save session:", err.Error()) } if m["Set-Cookie"][0][0:6] != "mysess" { t.Fatal("Cookie wasn't set!") } // ROUND 2 - check that the cookie can be retrieved req, err = http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create round 2 request", err) } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, ss.Codecs...) if err != nil { t.Fatal("Failed to make cookie value", err) } req.AddCookie(sessions.NewCookie(session.Name(), encoded, session.Options)) session, err = ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get round 2 session", err.Error()) } if session.Values["counter"] != 1 { t.Fatal("Retrieved session had wrong value:", session.Values["counter"]) } session.Values["counter"] = 9 // set new value for round 3 if err = ss.Save(req, headerOnlyResponseWriter(m), session); err != nil { t.Fatal("Failed to save session:", err.Error()) } // ROUND 3 - check that the cookie has been updated req, err = http.NewRequest("GET", "http://www.example.com", nil) if err != nil { t.Fatal("failed to create round 3 request", err) } req.AddCookie(sessions.NewCookie(session.Name(), encoded, session.Options)) session, err = ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get session round 3", err.Error()) } if session.Values["counter"] != 9 { t.Fatal("Retrieved session had wrong value in round 3:", session.Values["counter"]) } // RIUND 4 - check that the cookie can be deleted. w := httptest.NewRecorder() session.Options.MaxAge = -1 err = ss.Save(req, w, session) if err != nil { t.Errorf("saving session %v", err) } session, err = ss.Get(req, "mysess") if err != nil { t.Fatal("failed to get session round 4", err.Error()) } c := session.Values["counter"] if c != nil { t.Errorf("expected nil got %v", c) } }
func (c *CookieToken) SetToken(rw http.ResponseWriter, name, value string, options *sessions.Options) { http.SetCookie(rw, sessions.NewCookie(name, value, options)) }