From 5aa085bf419ec21ab110eebb8b6de7fd3ccfe6c7 Mon Sep 17 00:00:00 2001 From: yuyongsheng <173409900@qq.com> Date: Thu, 21 Apr 2016 09:57:44 +0800 Subject: [PATCH] 1. remove the invalid comments. 2. allow the user to config "Enable" store/get sessionId into/from http header 3. allow the user to config "Enable" get sessionId from Url query 4. when enable sessionId in http header, check the sessionName format as CanonicalMIMRHeaderKey, then panic if not. --- config.go | 38 +++++++++++++---------- hooks.go | 17 ++++++----- session/session.go | 76 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 95 insertions(+), 36 deletions(-) diff --git a/config.go b/config.go index 94e94a5f..f2c79634 100644 --- a/config.go +++ b/config.go @@ -83,14 +83,17 @@ type WebConfig struct { // SessionConfig holds session related config type SessionConfig struct { - SessionOn bool - SessionProvider string - SessionName string - SessionGCMaxLifetime int64 - SessionProviderConfig string - SessionCookieLifeTime int - SessionAutoSetCookie bool - SessionDomain string + SessionOn bool + SessionProvider string + SessionName string + SessionGCMaxLifetime int64 + SessionProviderConfig string + SessionCookieLifeTime int + SessionAutoSetCookie bool + SessionDomain string + EnableSidInHttpHeader bool // enable store/get the sessionId into/from http headers + SessionNameInHttpHeader string + EnableSidInUrlQuery bool // enable get the sessionId from Url Query params } // LogConfig holds Log related config @@ -183,14 +186,17 @@ func newBConfig() *Config { XSRFKey: "beegoxsrf", XSRFExpire: 0, Session: SessionConfig{ - SessionOn: false, - SessionProvider: "memory", - SessionName: "beegosessionID", - SessionGCMaxLifetime: 3600, - SessionProviderConfig: "", - SessionCookieLifeTime: 0, //set cookie default is the browser life - SessionAutoSetCookie: true, - SessionDomain: "", + SessionOn: false, + SessionProvider: "memory", + SessionName: "beegosessionID", + SessionGCMaxLifetime: 3600, + SessionProviderConfig: "", + SessionCookieLifeTime: 0, //set cookie default is the browser life + SessionAutoSetCookie: true, + SessionDomain: "", + EnableSidInHttpHeader: false, // enable store/get the sessionId into/from http headers + SessionNameInHttpHeader: "Beegosessionid", + EnableSidInUrlQuery: false, // enable get the sessionId from Url Query params }, }, Log: LogConfig{ diff --git a/hooks.go b/hooks.go index 610226b4..3dca1b8d 100644 --- a/hooks.go +++ b/hooks.go @@ -47,13 +47,16 @@ func registerSession() error { sessionConfig := AppConfig.String("sessionConfig") if sessionConfig == "" { conf := map[string]interface{}{ - "cookieName": BConfig.WebConfig.Session.SessionName, - "gclifetime": BConfig.WebConfig.Session.SessionGCMaxLifetime, - "providerConfig": filepath.ToSlash(BConfig.WebConfig.Session.SessionProviderConfig), - "secure": BConfig.Listen.EnableHTTPS, - "enableSetCookie": BConfig.WebConfig.Session.SessionAutoSetCookie, - "domain": BConfig.WebConfig.Session.SessionDomain, - "cookieLifeTime": BConfig.WebConfig.Session.SessionCookieLifeTime, + "cookieName": BConfig.WebConfig.Session.SessionName, + "gclifetime": BConfig.WebConfig.Session.SessionGCMaxLifetime, + "providerConfig": filepath.ToSlash(BConfig.WebConfig.Session.SessionProviderConfig), + "secure": BConfig.Listen.EnableHTTPS, + "enableSetCookie": BConfig.WebConfig.Session.SessionAutoSetCookie, + "domain": BConfig.WebConfig.Session.SessionDomain, + "cookieLifeTime": BConfig.WebConfig.Session.SessionCookieLifeTime, + "enableSidInHttpHeader": BConfig.WebConfig.Session.EnableSidInHttpHeader, + "sessionNameInHttpHeader": BConfig.WebConfig.Session.SessionNameInHttpHeader, + "enableSidInUrlQuery": BConfig.WebConfig.Session.EnableSidInUrlQuery, } confBytes, err := json.Marshal(conf) if err != nil { diff --git a/session/session.go b/session/session.go index 2c4b9351..53d89a27 100644 --- a/session/session.go +++ b/session/session.go @@ -31,10 +31,12 @@ import ( "crypto/rand" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "log" "net/http" + "net/textproto" "net/url" "os" "time" @@ -81,15 +83,18 @@ func Register(name string, provide Provider) { } type managerConfig struct { - CookieName string `json:"cookieName"` - EnableSetCookie bool `json:"enableSetCookie,omitempty"` - Gclifetime int64 `json:"gclifetime"` - Maxlifetime int64 `json:"maxLifetime"` - Secure bool `json:"secure"` - CookieLifeTime int `json:"cookieLifeTime"` - ProviderConfig string `json:"providerConfig"` - Domain string `json:"domain"` - SessionIDLength int64 `json:"sessionIDLength"` + CookieName string `json:"cookieName"` + EnableSetCookie bool `json:"enableSetCookie,omitempty"` + Gclifetime int64 `json:"gclifetime"` + Maxlifetime int64 `json:"maxLifetime"` + Secure bool `json:"secure"` + CookieLifeTime int `json:"cookieLifeTime"` + ProviderConfig string `json:"providerConfig"` + Domain string `json:"domain"` + SessionIDLength int64 `json:"sessionIDLength"` + EnableSidInHttpHeader bool `json:"enableSidInHttpHeader"` + SessionNameInHttpHeader string `json:"sessionNameInHttpHeader"` + EnableSidInUrlQuery bool `json:"enableSidInUrlQuery"` } // Manager contains Provider and its configuration. @@ -124,6 +129,23 @@ func NewManager(provideName, config string) (*Manager, error) { if cf.Maxlifetime == 0 { cf.Maxlifetime = cf.Gclifetime } + + if cf.EnableSidInHttpHeader { + if cf.SessionNameInHttpHeader == "" { + err = errors.New("SessionNameInHttpHeader is empty") + panic(err) + return nil, err + } + + strMimeHeader := textproto.CanonicalMIMEHeaderKey(cf.SessionNameInHttpHeader) + if cf.SessionNameInHttpHeader != strMimeHeader { + strErrMsg := "SessionNameInHttpHeader (" + cf.SessionNameInHttpHeader + ") has the wrong format, it should be like this : " + strMimeHeader + err = errors.New(strErrMsg) + panic(err) + return nil, err + } + } + err = provider.SessionInit(cf.Maxlifetime, cf.ProviderConfig) if err != nil { return nil, err @@ -149,12 +171,24 @@ func NewManager(provideName, config string) (*Manager, error) { func (manager *Manager) getSid(r *http.Request) (string, error) { cookie, errs := r.Cookie(manager.config.CookieName) if errs != nil || cookie.Value == "" || cookie.MaxAge < 0 { - errs := r.ParseForm() - if errs != nil { - return "", errs + var sid string + if manager.config.EnableSidInUrlQuery { + errs := r.ParseForm() + if errs != nil { + return "", errs + } + + sid = r.FormValue(manager.config.CookieName) + } + + // if not found in Cookie / param, then read it from request headers + if manager.config.EnableSidInHttpHeader && sid == "" { + sids, isFound := r.Header[manager.config.SessionNameInHttpHeader] + if isFound && len(sids) != 0 { + return sids[0], nil + } } - sid := r.FormValue(manager.config.CookieName) return sid, nil } @@ -198,11 +232,21 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se } r.AddCookie(cookie) + if manager.config.EnableSidInHttpHeader { + r.Header.Set(manager.config.SessionNameInHttpHeader, sid) + w.Header().Set(manager.config.SessionNameInHttpHeader, sid) + } + return } // SessionDestroy Destroy session by its id in http request cookie. func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) { + if manager.config.EnableSidInHttpHeader { + r.Header.Del(manager.config.SessionNameInHttpHeader) + w.Header().Del(manager.config.SessionNameInHttpHeader) + } + cookie, err := r.Cookie(manager.config.CookieName) if err != nil || cookie.Value == "" { return @@ -267,6 +311,12 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque http.SetCookie(w, cookie) } r.AddCookie(cookie) + + if manager.config.EnableSidInHttpHeader { + r.Header.Set(manager.config.SessionNameInHttpHeader, sid) + w.Header().Set(manager.config.SessionNameInHttpHeader, sid) + } + return }