github.com/godaddy-x/freego@v1.0.156/node/node_session.go (about)

     1  package node
     2  
     3  import (
     4  	"github.com/godaddy-x/freego/cache"
     5  	"github.com/godaddy-x/freego/utils"
     6  	"github.com/godaddy-x/freego/utils/jwt"
     7  )
     8  
     9  type Session interface {
    10  	GetId() string
    11  
    12  	GetStartTimestamp() int64
    13  
    14  	GetLastAccessTime() int64
    15  
    16  	GetTimeout() (int64, error) // 抛出校验会话异常
    17  
    18  	SetTimeout(t int64) error // 抛出校验会话异常
    19  
    20  	SetHost(host string)
    21  
    22  	GetHost() string
    23  
    24  	Touch() error // 刷新最后授权时间,抛出校验会话异常
    25  
    26  	Stop() error // 抛出校验会话异常
    27  
    28  	GetAttributeKeys() ([]string, error) // 抛出校验会话异常
    29  
    30  	GetAttribute(k string) (interface{}, error) // 抛出校验会话异常
    31  
    32  	SetAttribute(k string, v interface{}) error // 抛出校验会话异常
    33  
    34  	RemoveAttribute(k string) error // 抛出校验会话异常
    35  
    36  	Validate(accessToken, secretKey string) (int64, error) // 校验会话
    37  
    38  	Invalid() bool // 判断会话是否有效
    39  
    40  	IsTimeout() bool // 判断会话是否已超时
    41  }
    42  
    43  type SessionAware interface {
    44  	CreateSession(s Session) error // 保存session
    45  
    46  	ReadSession(s string) (Session, error) // 通过id读取session,抛出未知session异常
    47  
    48  	UpdateSession(s Session) error // 更新session,抛出未知session异常
    49  
    50  	DeleteSession(s Session) error // 删除session,抛出未知session异常
    51  
    52  	GetActiveSessions() []Session // 获取活动的session集合
    53  }
    54  
    55  type JWTSession struct {
    56  	Id             string
    57  	StartTimestamp int64
    58  	LastAccessTime int64
    59  	Timeout        int64
    60  	StopTime       int64
    61  	Host           string
    62  	Expire         bool
    63  	Attributes     map[string]interface{}
    64  }
    65  
    66  func (self *JWTSession) GetId() string {
    67  	return self.Id
    68  }
    69  
    70  func (self *JWTSession) GetStartTimestamp() int64 {
    71  	return self.StartTimestamp
    72  }
    73  
    74  func (self *JWTSession) GetLastAccessTime() int64 {
    75  	return self.LastAccessTime
    76  }
    77  
    78  func (self *JWTSession) GetTimeout() (int64, error) {
    79  	return self.Timeout, nil
    80  }
    81  
    82  func (self *JWTSession) SetTimeout(t int64) error {
    83  	self.Timeout = t
    84  	return nil
    85  }
    86  
    87  func (self *JWTSession) SetHost(host string) {
    88  	self.Host = host
    89  }
    90  
    91  func (self *JWTSession) GetHost() string {
    92  	return self.Host
    93  }
    94  
    95  func (self *JWTSession) Touch() error {
    96  	self.LastAccessTime = utils.UnixMilli()
    97  	return nil
    98  }
    99  
   100  func (self *JWTSession) Stop() error {
   101  	self.StopTime = utils.UnixMilli()
   102  	self.Expire = true
   103  	return nil
   104  }
   105  
   106  func (self *JWTSession) Validate(accessToken, secretKey string) (int64, error) {
   107  	if self.Expire {
   108  		return 0, utils.Error("session[", self.Id, "] expired")
   109  	} else if self.IsTimeout() {
   110  		return 0, utils.Error("session[", self.Id, "] timeout invalid")
   111  	}
   112  	// JWT二次校验
   113  	subject := &jwt.Subject{}
   114  	if len(self.GetHost()) > 0 {
   115  		subject.Payload = &jwt.Payload{Aud: self.GetHost()}
   116  	}
   117  	//if err := subject.Valid(accessToken, secretKey); err != nil {
   118  	//	return "", err
   119  	//}
   120  	return utils.StrToInt64(subject.Payload.Sub)
   121  }
   122  
   123  func (self *JWTSession) Invalid() bool {
   124  	if len(self.Id) > 0 && !self.Expire && self.StopTime == 0 {
   125  		return false
   126  	}
   127  	return true
   128  }
   129  
   130  func (self *JWTSession) IsTimeout() bool {
   131  	if utils.UnixMilli() > (self.LastAccessTime + self.Timeout) {
   132  		self.Stop()
   133  		return true
   134  	}
   135  	return false
   136  }
   137  
   138  func (self *JWTSession) GetAttributeKeys() ([]string, error) {
   139  	keys := []string{}
   140  	for k, _ := range self.Attributes {
   141  		keys = append(keys, k)
   142  	}
   143  	return keys, nil
   144  }
   145  
   146  func (self *JWTSession) GetAttribute(k string) (interface{}, error) {
   147  	if len(k) == 0 {
   148  		return nil, nil
   149  	}
   150  	if v, b := self.Attributes[k]; b {
   151  		return v, nil
   152  	}
   153  	return nil, nil
   154  }
   155  
   156  func (self *JWTSession) SetAttribute(k string, v interface{}) error {
   157  	self.Attributes[k] = v
   158  	return nil
   159  }
   160  
   161  func (self *JWTSession) RemoveAttribute(k string) error {
   162  	if len(k) == 0 {
   163  		return nil
   164  	}
   165  	if _, b := self.Attributes[k]; b {
   166  		delete(self.Attributes, k)
   167  	}
   168  	return nil
   169  }
   170  
   171  /********************************* Session Cache Impl *********************************/
   172  
   173  func NewLocalCacheSessionAware() *DefaultCacheSessionAware {
   174  	return &DefaultCacheSessionAware{
   175  		c: new(cache.LocalMapManager).NewCache(30, 10),
   176  	}
   177  }
   178  
   179  type DefaultCacheSessionAware struct {
   180  	c cache.Cache
   181  }
   182  
   183  func (self *DefaultCacheSessionAware) CreateSession(s Session) error {
   184  	if s.Invalid() {
   185  		return utils.Error("session[", s.GetId(), "] create invalid")
   186  	}
   187  	if err := s.Touch(); err != nil {
   188  		return err
   189  	}
   190  	//if err := s.Validate(); err != nil {
   191  	//	return err
   192  	//}
   193  	if t, err := s.GetTimeout(); err != nil {
   194  		return err
   195  	} else {
   196  		self.c.Put(s.GetId(), s, int(t/1000))
   197  	}
   198  	return nil
   199  }
   200  
   201  func (self *DefaultCacheSessionAware) ReadSession(s string) (Session, error) {
   202  	var session Session
   203  	if v, b, err := self.c.Get(s, session); err != nil {
   204  		return nil, utils.Error("session[", s, "] read err: ", err)
   205  	} else if b && v != nil {
   206  		if r, ok := v.(Session); ok {
   207  			if r.Invalid() {
   208  				return nil, utils.Error("session[", s, "] read invalid")
   209  			}
   210  			return r, nil
   211  		}
   212  	}
   213  	return nil, nil
   214  }
   215  
   216  func (self *DefaultCacheSessionAware) UpdateSession(s Session) error {
   217  	if err := s.Touch(); err != nil {
   218  		return err
   219  	}
   220  	if t, err := s.GetTimeout(); err != nil {
   221  		return err
   222  	} else {
   223  		self.c.Put(s.GetId(), s, int(t/1000))
   224  	}
   225  	return nil
   226  }
   227  
   228  func (self *DefaultCacheSessionAware) DeleteSession(s Session) error {
   229  	if s == nil {
   230  		return nil
   231  	}
   232  	s.Stop()
   233  	self.c.Del(s.GetId())
   234  	return nil
   235  }
   236  
   237  func (self *DefaultCacheSessionAware) GetActiveSessions() []Session {
   238  	return nil
   239  }