diff --git a/config/sessions.go b/config/sessions.go index e031051c..85f56f9f 100644 --- a/config/sessions.go +++ b/config/sessions.go @@ -63,6 +63,9 @@ type ( Provider string // Cookie string, the session's client cookie name, for example: "irissessionid" Cookie string + // DecodeCookie set it to true to decode the cookie key with base64 URLEncoding + // Defaults to false + DecodeCookie bool //Expires the date which the cookie must expires. Default infinitive/unlimited life Expires time.Time // GcDuration every how much duration(GcDuration) the memory should be clear for unused cookies (GcDuration) @@ -83,6 +86,7 @@ func DefaultSessions() Sessions { return Sessions{ Provider: "memory", // the default provider is "memory", if you set it to "" means that sessions are disabled. Cookie: DefaultCookieName, + DecodeCookie: false, Expires: CookieExpireNever, GcDuration: DefaultSessionGcDuration, DisableSubdomainPersistence: false, diff --git a/sessions/manager.go b/sessions/manager.go index d6cb8f72..64585359 100644 --- a/sessions/manager.go +++ b/sessions/manager.go @@ -42,11 +42,15 @@ func newManager(c config.Sessions) (*Manager, error) { if !found { return nil, ErrProviderNotFound.Format(c.Provider) } + if c.DecodeCookie { + c.Cookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie)) // change the cookie's name/key to a more safe(?) + // get the real value for your tests by: + //sessIdKey := url.QueryEscape(base64.URLEncoding.EncodeToString([]byte(iris.Config.Sessions.Cookie))) + } manager := &Manager{} manager.config = &c manager.provider = provider - manager.config.Cookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie)) // change the cookie's name/key to a more safe return manager, nil } @@ -90,7 +94,7 @@ func (m *Manager) Start(ctx context.IContext) store.IStore { cookie := fasthttp.AcquireCookie() // The RFC makes no mention of encoding url value, so here I think to encode both sessionid key and the value using the safe(to put and to use as cookie) url-encoding cookie.SetKey(m.config.Cookie) - cookie.SetValue(base64.URLEncoding.EncodeToString([]byte(sid))) + cookie.SetValue(sid) cookie.SetPath("/") if !m.config.DisableSubdomainPersistence { requestDomain := ctx.HostString() @@ -132,8 +136,7 @@ func (m *Manager) Start(ctx context.IContext) store.IStore { requestCtx.Response.Header.SetCookie(cookie) fasthttp.ReleaseCookie(cookie) } else { - sid, _ := base64.URLEncoding.DecodeString(cookieValue) - store, _ = m.provider.Read(string(sid)) + store, _ = m.provider.Read(cookieValue) } m.mu.Unlock() @@ -149,9 +152,7 @@ func (m *Manager) Destroy(ctx context.IContext) { m.mu.Lock() m.provider.Destroy(cookieValue) - ctx.RemoveCookie(m.config.Cookie) - m.mu.Unlock() } diff --git a/sessions/provider.go b/sessions/provider.go index 67655ade..cf841ced 100644 --- a/sessions/provider.go +++ b/sessions/provider.go @@ -55,9 +55,12 @@ func (p *Provider) Init(sid string) (store.IStore, error) { // Read returns the store which sid parameter is belongs func (p *Provider) Read(sid string) (store.IStore, error) { + p.mu.Lock() if elem, found := p.sessions[sid]; found { + p.mu.Unlock() // yes defer is slow return elem.Value.(store.IStore), nil } + p.mu.Unlock() // if not found sessionStore, err := p.Init(sid) return sessionStore, err @@ -66,12 +69,13 @@ func (p *Provider) Read(sid string) (store.IStore, error) { // Destroy always returns a nil error, for now. func (p *Provider) Destroy(sid string) error { + p.mu.Lock() if elem, found := p.sessions[sid]; found { elem.Value.(store.IStore).Destroy() delete(p.sessions, sid) p.list.Remove(elem) } - + p.mu.Unlock() return nil } diff --git a/sessions/providers/memory/store.go b/sessions/providers/memory/store.go index 9d89cab5..f53adecb 100644 --- a/sessions/providers/memory/store.go +++ b/sessions/providers/memory/store.go @@ -102,7 +102,10 @@ func (s *Store) SetLastAccessedTime(lastacc time.Time) { s.lastAccessedTime = lastacc } -// Destroy does nothing here, to destroy the session use the manager's .Destroy func +// Destroy func (s *Store) Destroy() { - // nothing + // clears without provider's update. + for key := range s.values { + delete(s.values, key) + } } diff --git a/sessions/providers/redis/redisstore.go b/sessions/providers/redis/redisstore.go index d5a66a7f..1473fd93 100644 --- a/sessions/providers/redis/redisstore.go +++ b/sessions/providers/redis/redisstore.go @@ -173,4 +173,8 @@ func (s *Store) SetLastAccessedTime(lastacc time.Time) { func (s *Store) Destroy() { // remove the whole value which is the s.values from real redis redis.Delete(s.sid) + for key := range s.values { + delete(s.values, key) + } + }