Closed dxvgef closed 7 years ago
By default the idle timeout is updated whenever the session is modified (not when it's only read). So a page refresh alone wouldn't trigger the idle timeout to be updated.
I've added a new *Manager.Use()
middleware, which checks whether there an idle timeout is set on the session manager, and if there is, will trigger the idle timeout update each time the session is read. If you wrap your handlers with that it should do what you need it too.
var sessionManager *scs.Manager
func main() {
sessionManager = scs.NewManager(redisstore.New(&redis.Pool{
MaxIdle: 10,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", "127.0.0.1:6379", redis.DialDatabase(0))
},
IdleTimeout: time.Duration(20 * time.Minute),
}))
sessionManager.IdleTimeout(20 * time.Minute)
sessionManager.Lifetime(time.Duration(2 * time.Hour))
mux := http.NewServeMux()
mux.HandleFunc("/put", putHandler)
mux.HandleFunc("/get", getHandler)
http.ListenAndServe(":4000", sessionManager.Use(mux))
}
Thanks
But I'm using the echo framework. How can I solve this problem?
I'm not hugely familiar with Echo but the code below seems to work for me:
package main
import (
"net/http"
"time"
"github.com/alexedwards/scs"
"github.com/alexedwards/scs/stores/redisstore"
"github.com/garyburd/redigo/redis"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
var sessionManager *scs.Manager
func main() {
sessionManager = scs.NewManager(redisstore.New(&redis.Pool{
MaxIdle: 10,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", "127.0.0.1:6379", redis.DialDatabase(0))
},
IdleTimeout: time.Duration(20 * time.Minute),
}))
sessionManager.IdleTimeout(20 * time.Minute)
sessionManager.Lifetime(time.Duration(2 * time.Hour))
e := echo.New()
e.Use(echo.WrapMiddleware(sessionManager.Use))
e.GET("/put", func(c echo.Context) error {
session := sessionManager.Load(c.Request())
err := session.PutString(c.Response().Writer, "message", "Hello world!")
if err != nil {
http.Error(c.Response().Writer, err.Error(), 500)
}
return c.String(http.StatusOK, "put")
})
e.GET("/get", func(c echo.Context) error {
session := sessionManager.Load(c.Request())
msg, err := session.GetString("message")
if err != nil {
http.Error(c.Response().Writer, err.Error(), 500)
}
return c.String(http.StatusOK, "result "+msg)
})
e.Start(":4000")
}
Thank you!
I think it's worth mentioning that redis.Pool.IdleTimeout has a different meaning than session.IdleTimeout. The redis client docs say that IdleTimeout has to do with stale client connections from redis.Pool to the redis.Server. It has nothing to do with invalidating the record within redis. The redis EXPIRE directive sets the timeout on the key.
The following is sufficient for controlling stale sessions within a web request:
SessionManager.IdleTimeout(20 * time.Minute)
SessionManager.Lifetime(time.Duration(2 * time.Hour)
Then use it in the middleware so that at least Touch()
is called which updates the deadline property.
This is my code snippet, I use Redis storage, and define the IdleTimeout value is 20 minutes and the Lifetime value is 2 hours, but the session data is always in 20 minutes of failure, the page refreshes does not seem to automatically extend the idle timeout time?