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  }