github.com/astaxie/beego@v1.12.3/session/sess_cookie.go (about) 1 // Copyright 2014 beego Author. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package session 16 17 import ( 18 "crypto/aes" 19 "crypto/cipher" 20 "encoding/json" 21 "net/http" 22 "net/url" 23 "sync" 24 ) 25 26 var cookiepder = &CookieProvider{} 27 28 // CookieSessionStore Cookie SessionStore 29 type CookieSessionStore struct { 30 sid string 31 values map[interface{}]interface{} // session data 32 lock sync.RWMutex 33 } 34 35 // Set value to cookie session. 36 // the value are encoded as gob with hash block string. 37 func (st *CookieSessionStore) Set(key, value interface{}) error { 38 st.lock.Lock() 39 defer st.lock.Unlock() 40 st.values[key] = value 41 return nil 42 } 43 44 // Get value from cookie session 45 func (st *CookieSessionStore) Get(key interface{}) interface{} { 46 st.lock.RLock() 47 defer st.lock.RUnlock() 48 if v, ok := st.values[key]; ok { 49 return v 50 } 51 return nil 52 } 53 54 // Delete value in cookie session 55 func (st *CookieSessionStore) Delete(key interface{}) error { 56 st.lock.Lock() 57 defer st.lock.Unlock() 58 delete(st.values, key) 59 return nil 60 } 61 62 // Flush Clean all values in cookie session 63 func (st *CookieSessionStore) Flush() error { 64 st.lock.Lock() 65 defer st.lock.Unlock() 66 st.values = make(map[interface{}]interface{}) 67 return nil 68 } 69 70 // SessionID Return id of this cookie session 71 func (st *CookieSessionStore) SessionID() string { 72 return st.sid 73 } 74 75 // SessionRelease Write cookie session to http response cookie 76 func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) { 77 st.lock.Lock() 78 encodedCookie, err := encodeCookie(cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, st.values) 79 st.lock.Unlock() 80 if err == nil { 81 cookie := &http.Cookie{Name: cookiepder.config.CookieName, 82 Value: url.QueryEscape(encodedCookie), 83 Path: "/", 84 HttpOnly: true, 85 Secure: cookiepder.config.Secure, 86 MaxAge: cookiepder.config.Maxage} 87 http.SetCookie(w, cookie) 88 } 89 } 90 91 type cookieConfig struct { 92 SecurityKey string `json:"securityKey"` 93 BlockKey string `json:"blockKey"` 94 SecurityName string `json:"securityName"` 95 CookieName string `json:"cookieName"` 96 Secure bool `json:"secure"` 97 Maxage int `json:"maxage"` 98 } 99 100 // CookieProvider Cookie session provider 101 type CookieProvider struct { 102 maxlifetime int64 103 config *cookieConfig 104 block cipher.Block 105 } 106 107 // SessionInit Init cookie session provider with max lifetime and config json. 108 // maxlifetime is ignored. 109 // json config: 110 // securityKey - hash string 111 // blockKey - gob encode hash string. it's saved as aes crypto. 112 // securityName - recognized name in encoded cookie string 113 // cookieName - cookie name 114 // maxage - cookie max life time. 115 func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error { 116 pder.config = &cookieConfig{} 117 err := json.Unmarshal([]byte(config), pder.config) 118 if err != nil { 119 return err 120 } 121 if pder.config.BlockKey == "" { 122 pder.config.BlockKey = string(generateRandomKey(16)) 123 } 124 if pder.config.SecurityName == "" { 125 pder.config.SecurityName = string(generateRandomKey(20)) 126 } 127 pder.block, err = aes.NewCipher([]byte(pder.config.BlockKey)) 128 if err != nil { 129 return err 130 } 131 pder.maxlifetime = maxlifetime 132 return nil 133 } 134 135 // SessionRead Get SessionStore in cooke. 136 // decode cooke string to map and put into SessionStore with sid. 137 func (pder *CookieProvider) SessionRead(sid string) (Store, error) { 138 maps, _ := decodeCookie(pder.block, 139 pder.config.SecurityKey, 140 pder.config.SecurityName, 141 sid, pder.maxlifetime) 142 if maps == nil { 143 maps = make(map[interface{}]interface{}) 144 } 145 rs := &CookieSessionStore{sid: sid, values: maps} 146 return rs, nil 147 } 148 149 // SessionExist Cookie session is always existed 150 func (pder *CookieProvider) SessionExist(sid string) bool { 151 return true 152 } 153 154 // SessionRegenerate Implement method, no used. 155 func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (Store, error) { 156 return nil, nil 157 } 158 159 // SessionDestroy Implement method, no used. 160 func (pder *CookieProvider) SessionDestroy(sid string) error { 161 return nil 162 } 163 164 // SessionGC Implement method, no used. 165 func (pder *CookieProvider) SessionGC() { 166 } 167 168 // SessionAll Implement method, return 0. 169 func (pder *CookieProvider) SessionAll() int { 170 return 0 171 } 172 173 // SessionUpdate Implement method, no used. 174 func (pder *CookieProvider) SessionUpdate(sid string) error { 175 return nil 176 } 177 178 func init() { 179 Register("cookie", cookiepder) 180 }