fc6b9ce0 by astaxie

fix #620 simple the sessionID generate

1 parent c4d8e4a2
...@@ -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 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!