func (m *mongoStore) Save(r *http.Request, w http.ResponseWriter, session *gSessions.Session) error { if session.Options.MaxAge < 0 { if err := m.delete(session); err != nil { return err } m.Token.SetToken(w, session.Name(), "", session.Options) return nil } if session.ID == "" { session.ID = bson.NewObjectId().Hex() } if err := m.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, m.Codecs...) if err != nil { return err } m.Token.SetToken(w, session.Name(), encoded, session.Options) return nil }
func SessionCookieFilter(cookieName string, opts *CookieOpts, keyPairs ...[]byte) restful.FilterFunction { codecs := securecookie.CodecsFromPairs(keyPairs...) return func(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { session := NewSession() if cookie, err := req.Request.Cookie(cookieName); err == nil { if err = securecookie.DecodeMulti(cookieName, cookie.Value, &session.store, codecs...); err == nil { } else { logrus.Warn(err) } } else { if err != http.ErrNoCookie { logrus.Warn(err) } } req.SetAttribute(AttrSessionKey, session) // I don't know how to write cookie in restful, so I use underneath negroni before hook resp.ResponseWriter.(negroni.ResponseWriter).Before(func(rw negroni.ResponseWriter) { if !session.IsModified() { return } if encoded, err := securecookie.EncodeMulti(cookieName, session.store, codecs...); err == nil { cookie := NewCookie(cookieName, encoded, opts) http.SetCookie(rw, cookie) } }) chain.ProcessFilter(req, resp) } }
func (s *Store) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.codecs...) if err != nil { return err } var expiresOn time.Time exOn := session.Values["expires_on"] if exOn == nil { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) } else { expiresOn = exOn.(time.Time) if expiresOn.Sub(time.Now().Add(time.Second*time.Duration(session.Options.MaxAge))) < 0 { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) } } ss := &Session{ Key: session.ID, Data: encoded, ExpiresOn: expiresOn, } if session.IsNew { return s.q.SaveSession(ss) } return s.q.UpdateSession(ss) }
func (s *RedisStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } c := s.storeHandler.GetRedisConnection() defer c.Close() 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)), "=") } c.Send("SET", "morioka_sess_"+session.ID, encoded) if err = c.Flush(); err != nil { return err } if _, err = c.Receive(); err != nil { return err } c.Send("EXPIRE", "morioka_sess_"+session.ID, 86400) if err = c.Flush(); err != nil { return err } if _, err = c.Receive(); err != nil { return err } return nil }
// 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 }
func (d *dalStore) Save(r *http.Request, w http.ResponseWriter, session *gSessions.Session) error { if session.Options.MaxAge < 0 { if err := d.delete(session); err != nil { return err } d.Token.SetToken(w, session.Name(), "", session.Options) return nil } if session.ID == "" { session.ID = dal.NewObjectID().Hex() } if err := d.save(session); err != nil { return err } //save just the id to the cookie, the rest will be saved in the dal store encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, d.Codecs...) if err != nil { return err } d.Token.SetToken(w, session.Name(), encoded, session.Options) return err }
func (m *MongoStore) upsert(session *sessions.Session) error { if !bson.IsObjectIdHex(session.ID) { return ErrInvalidId } var modified time.Time if val, ok := session.Values["modified"]; ok { modified, ok = val.(time.Time) if !ok { return errors.New("mongostore: invalid modified value") } } else { modified = time.Now() } encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...) if err != nil { return err } s := Session{ Id: bson.ObjectIdHex(session.ID), Data: encoded, Modified: modified, } _, err = m.coll.UpsertId(s.Id, &s) if err != nil { return err } 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 }
// Save adds a single session to the response. // // If the Options.MaxAge of the session is <= 0 then the session file will be // deleted from the store path. With this process it enforces the properly // session cookie handling so no need to trust in the cookie management in the // web browser. func (s *FilesystemStore) Save(r *http.Request, w http.ResponseWriter, session *Session) error { // Delete if max-age is <= 0 if session.Options.MaxAge <= 0 { if err := s.erase(session); err != nil { return err } http.SetCookie(w, NewCookie(session.Name(), "", session.Options)) return nil } 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, NewCookie(session.Name(), encoded, session.Options)) return nil }
// Return the session, the old XSRF token and an error if needed func getSession(req *http.Request, w http.ResponseWriter) (*sessions.Session, []uint8, error) { session, _ := dStore.Get(req, conf.SESSION_NAME) session.Options = &sessions.Options{ Path: "/", MaxAge: 7 * 24 * 60 * 60, // 7 days } var oldtoken []uint8 if session.Values["xsrf"] != nil { oldtoken = session.Values["xsrf"].([]uint8) } token := securecookie.GenerateRandomKey(32) session.Values["xsrf"] = token encoded, err := securecookie.EncodeMulti("XSRF-TOKEN", token, xsrfCodecs...) if err != nil { return nil, nil, fmt.Errorf("encode token failed: %s", err) } http.SetCookie(w, &http.Cookie{ Name: "XSRF-TOKEN", Value: encoded, Path: "/", }) return session, oldtoken, nil }
// GetAuthURL starts the authentication process with the requested provided. // It will return a URL that should be used to send users to. // // I would recommend using the BeginAuth instead of doing all of these steps // yourself. func GetAuthURL(providerName string, w http.ResponseWriter, r *http.Request) (string, error) { provider, err := goth.GetProvider(providerName) if err != nil { return "", err } state := base64.URLEncoding.EncodeToString(securecookie.GenerateRandomKey(stateLen * 3 / 4)) sess, err := provider.BeginAuth(state) if err != nil { return "", err } url, err := sess.GetAuthURL() if err != nil { return "", err } encoded, err := securecookie.EncodeMulti(CookieName, state+sess.Marshal(), codecs...) if err != nil { return "", err } http.SetCookie(w, cookie(CookieName, encoded, &CookieOptions)) return url, err }
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 *CookieStore) Save(r *http.Request, w http.ResponseWriter, session *Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } http.SetCookie(w, 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 writes encoded session.Values to a database record. // writes to http_sessions table by default. func (db *DatabaseStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, db.Codecs...) if err != nil { return err } fn := func(dbConn *sql.DB) error { // Write record to sessions table. var sessionCount int = -1 // Session exists? row := dbConn.QueryRow("SELECT COUNT(key) AS count FROM \""+SESSIONS_TABLE+"\" WHERE key = $1", session.ID) err := row.Scan(&sessionCount) if err != nil { return err } tx, err := dbConn.Begin() if err != nil { return err } if sessionCount > 0 { // update _, err = tx.Exec("UPDATE \""+SESSIONS_TABLE+"\" SET data = $1 WHERE key = $2", encoded, session.ID) if err != nil { return err } } else if sessionCount == 0 { // insert _, err = tx.Exec("INSERT INTO \""+SESSIONS_TABLE+"\" (key, data) VALUES($1,$2)", session.ID, encoded) if err != nil { return err } } else { // error err = errors.New("There was an error while trying to lookup a previous session.") return err } if err = tx.Commit(); err != nil { return err } return nil } return dbLib.ExecuteFn(fn) }
// save writes encoded session.Values to a file. func (s *FilesystemStore) save(session *Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } filename := s.path + "session_" + session.ID fileMutex.Lock() defer fileMutex.Unlock() return ioutil.WriteFile(filename, []byte(encoded), 0600) }
// save writes encoded session.Values using the memcache client func (s *DumbMemoryStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } s.Data[session.ID] = encoded return nil }
// save stores the session in redis. func (s *RediStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } conn := s.Pool.Get() defer conn.Close() if err = conn.Err(); err != nil { return err } _, err = conn.Do("SETEX", "session_"+session.ID, session.Options.MaxAge, encoded) return err }
// save writes encoded session.Values to db. func (s *DbStore) save(session *Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } sessionInfo := &model.SessionInfo{Id: session.ID, Content: encoded, Age: session.Options.MaxAge} if (&model.SessionInfo{Id: session.ID}).Exist() { sessionInfo.Update() } else { sessionInfo.Insert() } 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 }
// Save adds a single session to the response. func (s *RedisStore) 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 } 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 writes encoded session.Values to a database record. // writes to http_sessions table by default. func (db *PGStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, db.Codecs...) if err != nil { return err } var createdOn time.Time var expiresOn time.Time crOn := session.Values["created_on"] exOn := session.Values["expires_on"] if crOn == nil { createdOn = time.Now() } else { createdOn = crOn.(time.Time) } if exOn == nil { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) } else { expiresOn = exOn.(time.Time) if expiresOn.Sub(time.Now().Add(time.Second*time.Duration(session.Options.MaxAge))) < 0 { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) } } s := Session{ Key: session.ID, Data: encoded, CreatedOn: createdOn, ExpiresOn: expiresOn, ModifiedOn: time.Now(), } if session.IsNew { err = db.DbMap.Insert(&s) } else { _, err = db.DbMap.Exec("update http_sessions set data=$1, modified_on=$2, expires_on=$3 where key=$4", s.Data, s.ModifiedOn, s.ExpiresOn, s.Key) } return err }
// save writes encoded session.Values into redis. func (s *RedisStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } c := s.redisPool.Get() defer c.Close() _, err = c.Do("SET", "s:"+session.ID, encoded) if err != nil { return err } _, err = c.Do("EXPIRE", "s:"+session.ID, session.Options.MaxAge) return err }
// save writes encoded session.Values to a file. func (s *FileStore) save(session *Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } filename := s.path + "session_" + session.ID fileMutex.Lock() defer fileMutex.Unlock() fp, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) if err != nil { return err } if _, err = fp.Write([]byte(encoded)); err != nil { return err } fp.Close() return 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 }
// 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 (d *dalStore) save(session *gSessions.Session) error { if !dal.IsObjectIDHex(session.ID) { return nSessions.ErrInvalidId } conn := d.connection.Clone() defer conn.Close() db := conn.DB(d.database) c := db.C(d.collection) var modified time.Time if val, ok := session.Values["modified"]; ok { modified, ok = val.(time.Time) if !ok { return nSessions.ErrInvalidModified } } else { modified = time.Now() } encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, d.Codecs...) if err != nil { return err } id := dal.ObjectIDHex(session.ID) s := dalSession{ ID: id, Data: encoded, Modified: modified, } _, err = c.SaveID(id, &s) if err != nil { return err } return nil }
func (m *mongoStore) save(session *gSessions.Session) error { if !bson.IsObjectIdHex(session.ID) { return nSessions.ErrInvalidId } var modified time.Time if val, ok := session.Values["modified"]; ok { modified, ok = val.(time.Time) if !ok { return nSessions.ErrInvalidModified } } else { modified = time.Now() } encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...) if err != nil { return err } s := mongoSession{ Data: encoded, Modified: modified, } connection := m.session.Clone() defer connection.Close() db := connection.DB(m.database) c := db.C(m.collection) _, err = c.UpsertId(bson.ObjectIdHex(session.ID), &s) if err != nil { return err } return nil }
func (m *SqliteStore) save(session *sessions.Session) error { if session.IsNew == true { return m.insert(session) } var createdOn time.Time var expiresOn time.Time crOn := session.Values["created_on"] if crOn == nil { createdOn = time.Now() } else { createdOn = crOn.(time.Time) } exOn := session.Values["expires_on"] if exOn == nil { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) log.Print("nil") } else { expiresOn = exOn.(time.Time) if expiresOn.Sub(time.Now().Add(time.Second*time.Duration(session.Options.MaxAge))) < 0 { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) } } delete(session.Values, "created_on") delete(session.Values, "expires_on") delete(session.Values, "modified_on") encoded, encErr := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...) if encErr != nil { return encErr } _, updErr := m.stmtUpdate.Exec(encoded, createdOn, expiresOn, session.ID) if updErr != nil { return updErr } 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) } }