fix #620 simple the sessionID generate
Showing
1 changed file
with
40 additions
and
57 deletions
| ... | @@ -28,19 +28,13 @@ | ... | @@ -28,19 +28,13 @@ |
| 28 | package session | 28 | package session |
| 29 | 29 | ||
| 30 | import ( | 30 | import ( |
| 31 | "crypto/hmac" | ||
| 32 | "crypto/md5" | ||
| 33 | "crypto/rand" | 31 | "crypto/rand" |
| 34 | "crypto/sha1" | ||
| 35 | "encoding/hex" | 32 | "encoding/hex" |
| 36 | "encoding/json" | 33 | "encoding/json" |
| 37 | "fmt" | 34 | "fmt" |
| 38 | "io" | ||
| 39 | "net/http" | 35 | "net/http" |
| 40 | "net/url" | 36 | "net/url" |
| 41 | "time" | 37 | "time" |
| 42 | |||
| 43 | "github.com/astaxie/beego/utils" | ||
| 44 | ) | 38 | ) |
| 45 | 39 | ||
| 46 | // SessionStore contains all data for one session process with specific id. | 40 | // SessionStore contains all data for one session process with specific id. |
| ... | @@ -81,16 +75,15 @@ func Register(name string, provide Provider) { | ... | @@ -81,16 +75,15 @@ func Register(name string, provide Provider) { |
| 81 | } | 75 | } |
| 82 | 76 | ||
| 83 | type managerConfig struct { | 77 | type managerConfig struct { |
| 84 | CookieName string `json:"cookieName"` | 78 | CookieName string `json:"cookieName"` |
| 85 | EnableSetCookie bool `json:"enableSetCookie,omitempty"` | 79 | EnableSetCookie bool `json:"enableSetCookie,omitempty"` |
| 86 | Gclifetime int64 `json:"gclifetime"` | 80 | Gclifetime int64 `json:"gclifetime"` |
| 87 | Maxlifetime int64 `json:"maxLifetime"` | 81 | Maxlifetime int64 `json:"maxLifetime"` |
| 88 | Secure bool `json:"secure"` | 82 | Secure bool `json:"secure"` |
| 89 | SessionIDHashFunc string `json:"sessionIDHashFunc"` | 83 | CookieLifeTime int `json:"cookieLifeTime"` |
| 90 | SessionIDHashKey string `json:"sessionIDHashKey"` | 84 | ProviderConfig string `json:"providerConfig"` |
| 91 | CookieLifeTime int `json:"cookieLifeTime"` | 85 | Domain string `json:"domain"` |
| 92 | ProviderConfig string `json:"providerConfig"` | 86 | SessionIdLength int64 `json:"sessionIdLength"` |
| 93 | Domain string `json:"domain"` | ||
| 94 | } | 87 | } |
| 95 | 88 | ||
| 96 | // Manager contains Provider and its configuration. | 89 | // Manager contains Provider and its configuration. |
| ... | @@ -129,11 +122,9 @@ func NewManager(provideName, config string) (*Manager, error) { | ... | @@ -129,11 +122,9 @@ func NewManager(provideName, config string) (*Manager, error) { |
| 129 | if err != nil { | 122 | if err != nil { |
| 130 | return nil, err | 123 | return nil, err |
| 131 | } | 124 | } |
| 132 | if cf.SessionIDHashFunc == "" { | 125 | |
| 133 | cf.SessionIDHashFunc = "sha1" | 126 | if cf.SessionIdLength == 0 { |
| 134 | } | 127 | cf.SessionIdLength = 16 |
| 135 | if cf.SessionIDHashKey == "" { | ||
| 136 | cf.SessionIDHashKey = string(generateRandomKey(16)) | ||
| 137 | } | 128 | } |
| 138 | 129 | ||
| 139 | return &Manager{ | 130 | return &Manager{ |
| ... | @@ -144,11 +135,14 @@ func NewManager(provideName, config string) (*Manager, error) { | ... | @@ -144,11 +135,14 @@ func NewManager(provideName, config string) (*Manager, error) { |
| 144 | 135 | ||
| 145 | // Start session. generate or read the session id from http request. | 136 | // Start session. generate or read the session id from http request. |
| 146 | // if session id exists, return SessionStore with this id. | 137 | // if session id exists, return SessionStore with this id. |
| 147 | func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session SessionStore) { | 138 | func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session SessionStore, err error) { |
| 148 | cookie, err := r.Cookie(manager.config.CookieName) | 139 | cookie, errs := r.Cookie(manager.config.CookieName) |
| 149 | if err != nil || cookie.Value == "" { | 140 | if errs != nil || cookie.Value == "" { |
| 150 | sid := manager.sessionId(r) | 141 | sid, errs := manager.sessionId(r) |
| 151 | session, _ = manager.provider.SessionRead(sid) | 142 | if errs != nil { |
| 143 | return nil, errs | ||
| 144 | } | ||
| 145 | session, err = manager.provider.SessionRead(sid) | ||
| 152 | cookie = &http.Cookie{Name: manager.config.CookieName, | 146 | cookie = &http.Cookie{Name: manager.config.CookieName, |
| 153 | Value: url.QueryEscape(sid), | 147 | Value: url.QueryEscape(sid), |
| 154 | Path: "/", | 148 | Path: "/", |
| ... | @@ -163,12 +157,18 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se | ... | @@ -163,12 +157,18 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se |
| 163 | } | 157 | } |
| 164 | r.AddCookie(cookie) | 158 | r.AddCookie(cookie) |
| 165 | } else { | 159 | } else { |
| 166 | sid, _ := url.QueryUnescape(cookie.Value) | 160 | sid, errs := url.QueryUnescape(cookie.Value) |
| 161 | if errs != nil { | ||
| 162 | return nil, errs | ||
| 163 | } | ||
| 167 | if manager.provider.SessionExist(sid) { | 164 | if manager.provider.SessionExist(sid) { |
| 168 | session, _ = manager.provider.SessionRead(sid) | 165 | session, err = manager.provider.SessionRead(sid) |
| 169 | } else { | 166 | } else { |
| 170 | sid = manager.sessionId(r) | 167 | sid, err = manager.sessionId(r) |
| 171 | session, _ = manager.provider.SessionRead(sid) | 168 | if err != nil { |
| 169 | return nil, err | ||
| 170 | } | ||
| 171 | session, err = manager.provider.SessionRead(sid) | ||
| 172 | cookie = &http.Cookie{Name: manager.config.CookieName, | 172 | cookie = &http.Cookie{Name: manager.config.CookieName, |
| 173 | Value: url.QueryEscape(sid), | 173 | Value: url.QueryEscape(sid), |
| 174 | Path: "/", | 174 | Path: "/", |
| ... | @@ -219,7 +219,10 @@ func (manager *Manager) GC() { | ... | @@ -219,7 +219,10 @@ func (manager *Manager) GC() { |
| 219 | 219 | ||
| 220 | // Regenerate a session id for this SessionStore who's id is saving in http request. | 220 | // Regenerate a session id for this SessionStore who's id is saving in http request. |
| 221 | func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Request) (session SessionStore) { | 221 | func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Request) (session SessionStore) { |
| 222 | sid := manager.sessionId(r) | 222 | sid, err := manager.sessionId(r) |
| 223 | if err != nil { | ||
| 224 | return | ||
| 225 | } | ||
| 223 | cookie, err := r.Cookie(manager.config.CookieName) | 226 | cookie, err := r.Cookie(manager.config.CookieName) |
| 224 | if err != nil && cookie.Value == "" { | 227 | if err != nil && cookie.Value == "" { |
| 225 | //delete old cookie | 228 | //delete old cookie |
| ... | @@ -251,36 +254,16 @@ func (manager *Manager) GetActiveSession() int { | ... | @@ -251,36 +254,16 @@ func (manager *Manager) GetActiveSession() int { |
| 251 | return manager.provider.SessionAll() | 254 | return manager.provider.SessionAll() |
| 252 | } | 255 | } |
| 253 | 256 | ||
| 254 | // Set hash function for generating session id. | ||
| 255 | func (manager *Manager) SetHashFunc(hasfunc, hashkey string) { | ||
| 256 | manager.config.SessionIDHashFunc = hasfunc | ||
| 257 | manager.config.SessionIDHashKey = hashkey | ||
| 258 | } | ||
| 259 | |||
| 260 | // Set cookie with https. | 257 | // Set cookie with https. |
| 261 | func (manager *Manager) SetSecure(secure bool) { | 258 | func (manager *Manager) SetSecure(secure bool) { |
| 262 | manager.config.Secure = secure | 259 | manager.config.Secure = secure |
| 263 | } | 260 | } |
| 264 | 261 | ||
| 265 | // generate session id with rand string, unix nano time, remote addr by hash function. | 262 | func (manager *Manager) sessionId(r *http.Request) (string, error) { |
| 266 | func (manager *Manager) sessionId(r *http.Request) (sid string) { | 263 | b := make([]byte, manager.config.SessionIdLength) |
| 267 | bs := make([]byte, 32) | 264 | n, err := rand.Read(b) |
| 268 | if n, err := io.ReadFull(rand.Reader, bs); n != 32 || err != nil { | 265 | if n != len(b) || err != nil { |
| 269 | bs = utils.RandomCreateBytes(32) | 266 | return "", fmt.Errorf("Could not successfully read from the system CSPRNG.") |
| 270 | } | ||
| 271 | sig := fmt.Sprintf("%s%d%s", r.RemoteAddr, time.Now().UnixNano(), bs) | ||
| 272 | if manager.config.SessionIDHashFunc == "md5" { | ||
| 273 | h := md5.New() | ||
| 274 | h.Write([]byte(sig)) | ||
| 275 | sid = hex.EncodeToString(h.Sum(nil)) | ||
| 276 | } else if manager.config.SessionIDHashFunc == "sha1" { | ||
| 277 | h := hmac.New(sha1.New, []byte(manager.config.SessionIDHashKey)) | ||
| 278 | fmt.Fprintf(h, "%s", sig) | ||
| 279 | sid = hex.EncodeToString(h.Sum(nil)) | ||
| 280 | } else { | ||
| 281 | h := hmac.New(sha1.New, []byte(manager.config.SessionIDHashKey)) | ||
| 282 | fmt.Fprintf(h, "%s", sig) | ||
| 283 | sid = hex.EncodeToString(h.Sum(nil)) | ||
| 284 | } | 267 | } |
| 285 | return | 268 | return hex.EncodeToString(b), nil |
| 286 | } | 269 | } | ... | ... |
-
Please register or sign in to post a comment