cookie是存儲在瀏覽器端,session是服務器端
cookie是有時間限制的,分會話cookie和持久cookie,如果不設置時間,那周期就是創建到瀏覽器關閉為止.這種是會話cookie,一般保存在內存中
如果設置了過期時間,瀏覽器就會把cookie保存在硬盤中.
Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據可以保存在集群、數據庫、文件中;
Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。
在go語言中的cookie結構體
type Cookie struct { Name string Value string Path string Domain string Expires time.Time RawExpires string // MaxAge=0 means no 'Max-Age' attribute specified. // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0' // MaxAge>0 means Max-Age attribute present and given in seconds MaxAge int Secure bool HttpOnly bool Raw string Unparsed []string // Raw text of unparsed attribute-value pairs }
全局的session管理器
type Manager struct { cookieName string // private cookiename lock sync.Mutex // protects session provider Provider maxLifeTime int64 } func NewManager(provideName, cookieName string, maxLifeTime int64) (*Manager, error) { provider, ok := provides[provideName] if !ok { return nil, fmt.Errorf("session: unknown provide %q (forgotten import?)", provideName) } return &Manager{provider: provider, cookieName: cookieName, maxLifeTime: maxLifeTime}, nil }
package memory import ( "container/list" "github.com/astaxie/session" "sync" "time" ) //內存存儲的session機制 var pder = &Provider{list: list.New()} type SessionStore struct { sid string //session id唯一標示 timeAccessed time.Time //最后訪問時間 value map[interface{}]interface{} //session里面存儲的值 } func (st *SessionStore) Set(key, value interface{}) error { st.value[key] = value pder.SessionUpdate(st.sid) return nil } func (st *SessionStore) Get(key interface{}) interface{} { pder.SessionUpdate(st.sid) if v, ok := st.value[key]; ok { return v } else { return nil } } func (st *SessionStore) Delete(key interface{}) error { delete(st.value, key) pder.SessionUpdate(st.sid) return nil } func (st *SessionStore) SessionID() string { return st.sid } type Provider struct { lock sync.Mutex //用來鎖 sessions map[string]*list.Element //用來存儲在內存 list *list.List //用來做gc } func (pder *Provider) SessionInit(sid string) (session.Session, error) { pder.lock.Lock() defer pder.lock.Unlock() v := make(map[interface{}]interface{}, 0) newsess := &SessionStore{sid: sid, timeAccessed: time.Now(), value: v} element := pder.list.PushBack(newsess) pder.sessions[sid] = element return newsess, nil } func (pder *Provider) SessionRead(sid string) (session.Session, error) { if element, ok := pder.sessions[sid]; ok { return element.Value.(*SessionStore), nil } else { sess, err := pder.SessionInit(sid) return sess, err } return nil, nil } func (pder *Provider) SessionDestroy(sid string) error { if element, ok := pder.sessions[sid]; ok { delete(pder.sessions, sid) pder.list.Remove(element) return nil } return nil } func (pder *Provider) SessionGC(maxlifetime int64) { pder.lock.Lock() defer pder.lock.Unlock() for { element := pder.list.Back() if element == nil { break } if (element.Value.(*SessionStore).timeAccessed.Unix() + maxlifetime) < time.Now().Unix() { pder.list.Remove(element) delete(pder.sessions, element.Value.(*SessionStore).sid) } else { break } } } func (pder *Provider) SessionUpdate(sid string) error { pder.lock.Lock() defer pder.lock.Unlock() if element, ok := pder.sessions[sid]; ok { element.Value.(*SessionStore).timeAccessed = time.Now() pder.list.MoveToFront(element) return nil } return nil } func init() { //自動運行init函數 pder.sessions = make(map[string]*list.Element, 0) session.Register("memory", pder) }