2014-01-05 06:48:36 +00:00
|
|
|
package session
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/aes"
|
|
|
|
"crypto/cipher"
|
|
|
|
"encoding/json"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
var cookiepder = &CookieProvider{}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Cookie SessionStore
|
2014-01-05 06:48:36 +00:00
|
|
|
type CookieSessionStore struct {
|
|
|
|
sid string
|
2014-01-28 17:05:56 +00:00
|
|
|
values map[interface{}]interface{} // session data
|
2014-01-05 06:48:36 +00:00
|
|
|
lock sync.RWMutex
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Set value to cookie session.
|
|
|
|
// the value are encoded as gob with hash block string.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (st *CookieSessionStore) Set(key, value interface{}) error {
|
|
|
|
st.lock.Lock()
|
|
|
|
defer st.lock.Unlock()
|
|
|
|
st.values[key] = value
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Get value from cookie session
|
2014-01-05 06:48:36 +00:00
|
|
|
func (st *CookieSessionStore) Get(key interface{}) interface{} {
|
|
|
|
st.lock.RLock()
|
|
|
|
defer st.lock.RUnlock()
|
|
|
|
if v, ok := st.values[key]; ok {
|
|
|
|
return v
|
|
|
|
} else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Delete value in cookie session
|
2014-01-05 06:48:36 +00:00
|
|
|
func (st *CookieSessionStore) Delete(key interface{}) error {
|
|
|
|
st.lock.Lock()
|
|
|
|
defer st.lock.Unlock()
|
|
|
|
delete(st.values, key)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Clean all values in cookie session
|
2014-01-05 06:48:36 +00:00
|
|
|
func (st *CookieSessionStore) Flush() error {
|
|
|
|
st.lock.Lock()
|
|
|
|
defer st.lock.Unlock()
|
|
|
|
st.values = make(map[interface{}]interface{})
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Return id of this cookie session
|
2014-01-05 06:48:36 +00:00
|
|
|
func (st *CookieSessionStore) SessionID() string {
|
|
|
|
return st.sid
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Write cookie session to http response cookie
|
2014-01-05 06:48:36 +00:00
|
|
|
func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) {
|
|
|
|
str, err := encodeCookie(cookiepder.block,
|
|
|
|
cookiepder.config.SecurityKey,
|
|
|
|
cookiepder.config.SecurityName,
|
|
|
|
st.values)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
cookie := &http.Cookie{Name: cookiepder.config.CookieName,
|
|
|
|
Value: url.QueryEscape(str),
|
|
|
|
Path: "/",
|
|
|
|
HttpOnly: true,
|
2014-04-08 10:16:16 +00:00
|
|
|
Secure: cookiepder.config.Secure,
|
|
|
|
MaxAge: cookiepder.config.Maxage}
|
2014-01-05 06:48:36 +00:00
|
|
|
http.SetCookie(w, cookie)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
type cookieConfig struct {
|
|
|
|
SecurityKey string `json:"securityKey"`
|
|
|
|
BlockKey string `json:"blockKey"`
|
|
|
|
SecurityName string `json:"securityName"`
|
|
|
|
CookieName string `json:"cookieName"`
|
|
|
|
Secure bool `json:"secure"`
|
|
|
|
Maxage int `json:"maxage"`
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Cookie session provider
|
2014-01-05 06:48:36 +00:00
|
|
|
type CookieProvider struct {
|
|
|
|
maxlifetime int64
|
|
|
|
config *cookieConfig
|
|
|
|
block cipher.Block
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Init cookie session provider with max lifetime and config json.
|
|
|
|
// maxlifetime is ignored.
|
|
|
|
// json config:
|
|
|
|
// securityKey - hash string
|
|
|
|
// blockKey - gob encode hash string. it's saved as aes crypto.
|
|
|
|
// securityName - recognized name in encoded cookie string
|
|
|
|
// cookieName - cookie name
|
|
|
|
// maxage - cookie max life time.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error {
|
|
|
|
pder.config = &cookieConfig{}
|
|
|
|
err := json.Unmarshal([]byte(config), pder.config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if pder.config.BlockKey == "" {
|
|
|
|
pder.config.BlockKey = string(generateRandomKey(16))
|
|
|
|
}
|
|
|
|
if pder.config.SecurityName == "" {
|
|
|
|
pder.config.SecurityName = string(generateRandomKey(20))
|
|
|
|
}
|
|
|
|
pder.block, err = aes.NewCipher([]byte(pder.config.BlockKey))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2014-03-26 05:51:35 +00:00
|
|
|
pder.maxlifetime = maxlifetime
|
2014-01-05 06:48:36 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Get SessionStore in cooke.
|
|
|
|
// decode cooke string to map and put into SessionStore with sid.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionRead(sid string) (SessionStore, error) {
|
2014-01-08 15:24:31 +00:00
|
|
|
maps, _ := decodeCookie(pder.block,
|
2014-01-05 06:48:36 +00:00
|
|
|
pder.config.SecurityKey,
|
|
|
|
pder.config.SecurityName,
|
|
|
|
sid, pder.maxlifetime)
|
2014-01-08 15:24:31 +00:00
|
|
|
if maps == nil {
|
|
|
|
maps = make(map[interface{}]interface{})
|
|
|
|
}
|
|
|
|
rs := &CookieSessionStore{sid: sid, values: maps}
|
2014-01-05 06:48:36 +00:00
|
|
|
return rs, nil
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Cookie session is always existed
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionExist(sid string) bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Implement method, no used.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Implement method, no used.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionDestroy(sid string) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Implement method, no used.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionGC() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Implement method, return 0.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionAll() int {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2014-01-28 17:05:56 +00:00
|
|
|
// Implement method, no used.
|
2014-01-05 06:48:36 +00:00
|
|
|
func (pder *CookieProvider) SessionUpdate(sid string) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
Register("cookie", cookiepder)
|
|
|
|
}
|