2020-11-06 19:43:57 +01:00
|
|
|
package session
|
2020-11-06 19:32:56 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
"github.com/gofiber/fiber/v2/utils"
|
|
|
|
"github.com/valyala/fasthttp"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Session struct {
|
2020-11-06 19:43:57 +01:00
|
|
|
ctx *fiber.Ctx
|
|
|
|
config *Store
|
|
|
|
db *db
|
|
|
|
id string
|
|
|
|
fresh bool
|
2020-11-06 19:32:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fresh is true if the current session is new or existing
|
|
|
|
func (s *Session) Fresh() bool {
|
|
|
|
return s.fresh
|
|
|
|
}
|
|
|
|
|
|
|
|
// ID returns the session id
|
|
|
|
func (s *Session) ID() string {
|
|
|
|
return s.id
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get will return the value
|
|
|
|
func (s *Session) Get(key string) interface{} {
|
|
|
|
return s.db.Get(key)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set will update or create a new key value
|
|
|
|
func (s *Session) Set(key string, val interface{}) {
|
|
|
|
s.db.Set(key, val)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete will delete the value
|
|
|
|
func (s *Session) Delete(key string) {
|
|
|
|
s.db.Delete(key)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset will clear the session and remove from storage
|
|
|
|
func (s *Session) Reset() error {
|
|
|
|
s.db.Reset()
|
2020-11-06 19:43:57 +01:00
|
|
|
return s.config.Storage.Delete(s.id)
|
2020-11-06 19:32:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Save will update the storage and client cookie
|
|
|
|
func (s *Session) Save() error {
|
|
|
|
// Expire session if no data is present ( aka reset )
|
|
|
|
if s.db.Len() <= 0 {
|
|
|
|
// Delete cookie
|
|
|
|
s.deleteCookie()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert book to bytes
|
|
|
|
data, err := s.db.MarshalMsg(nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// pass raw bytes with session id to provider
|
2020-11-06 19:43:57 +01:00
|
|
|
if err := s.config.Storage.Set(s.id, data, s.config.Expiration); err != nil {
|
2020-11-06 19:32:56 +01:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// release db back to pool to be re-used on next request
|
|
|
|
releaseDB(s.db)
|
|
|
|
|
|
|
|
// Create cookie with the session ID
|
|
|
|
s.setCookie()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Session) setCookie() {
|
|
|
|
fcookie := fasthttp.AcquireCookie()
|
2020-11-06 19:43:57 +01:00
|
|
|
fcookie.SetKey(s.config.Cookie.Name)
|
2020-11-06 19:32:56 +01:00
|
|
|
fcookie.SetValue(s.id)
|
2020-11-06 19:43:57 +01:00
|
|
|
fcookie.SetPath(s.config.Cookie.Path)
|
|
|
|
fcookie.SetDomain(s.config.Cookie.Domain)
|
|
|
|
fcookie.SetMaxAge(int(s.config.Expiration))
|
|
|
|
fcookie.SetExpire(time.Now().Add(s.config.Expiration))
|
|
|
|
fcookie.SetSecure(s.config.Cookie.Secure)
|
|
|
|
fcookie.SetHTTPOnly(s.config.Cookie.HTTPOnly)
|
|
|
|
|
|
|
|
switch utils.ToLower(s.config.Cookie.SameSite) {
|
2020-11-06 19:32:56 +01:00
|
|
|
case "strict":
|
|
|
|
fcookie.SetSameSite(fasthttp.CookieSameSiteStrictMode)
|
|
|
|
case "none":
|
|
|
|
fcookie.SetSameSite(fasthttp.CookieSameSiteNoneMode)
|
|
|
|
default:
|
|
|
|
fcookie.SetSameSite(fasthttp.CookieSameSiteLaxMode)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.ctx.Response().Header.SetCookie(fcookie)
|
|
|
|
fasthttp.ReleaseCookie(fcookie)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Session) deleteCookie() {
|
2020-11-06 19:43:57 +01:00
|
|
|
s.ctx.Request().Header.DelCookie(s.config.Cookie.Name)
|
|
|
|
s.ctx.Response().Header.DelCookie(s.config.Cookie.Name)
|
2020-11-06 19:32:56 +01:00
|
|
|
|
|
|
|
fcookie := fasthttp.AcquireCookie()
|
2020-11-06 19:43:57 +01:00
|
|
|
fcookie.SetKey(s.config.Cookie.Name)
|
|
|
|
fcookie.SetPath(s.config.Cookie.Path)
|
|
|
|
fcookie.SetDomain(s.config.Cookie.Domain)
|
|
|
|
fcookie.SetMaxAge(int(s.config.Expiration))
|
2020-11-06 19:32:56 +01:00
|
|
|
fcookie.SetExpire(time.Now().Add(-1 * time.Minute))
|
2020-11-06 19:43:57 +01:00
|
|
|
fcookie.SetSecure(s.config.Cookie.Secure)
|
|
|
|
fcookie.SetHTTPOnly(s.config.Cookie.HTTPOnly)
|
2020-11-06 19:32:56 +01:00
|
|
|
|
2020-11-06 19:43:57 +01:00
|
|
|
switch utils.ToLower(s.config.Cookie.SameSite) {
|
2020-11-06 19:32:56 +01:00
|
|
|
case "strict":
|
|
|
|
fcookie.SetSameSite(fasthttp.CookieSameSiteStrictMode)
|
|
|
|
case "none":
|
|
|
|
fcookie.SetSameSite(fasthttp.CookieSameSiteNoneMode)
|
|
|
|
default:
|
|
|
|
fcookie.SetSameSite(fasthttp.CookieSameSiteLaxMode)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.ctx.Response().Header.SetCookie(fcookie)
|
|
|
|
fasthttp.ReleaseCookie(fcookie)
|
|
|
|
}
|