Skip to content

Latest commit

 

History

History
212 lines (198 loc) · 9.93 KB

05.md

File metadata and controls

212 lines (198 loc) · 9.93 KB

HttpSession

###导航:

  1. 操作流程
  2. HttpSessionManager
  3. 使用HttpSession
  4. CookieToken机制
  5. FormToken机制
  6. HttpSession销毁通知

操作流程

Leafveingo启动 -> 初始化HttpSessionManager(包括自动GC) -> 请求获取session -> 操作Cookie -> 得到session -> session数据存储或其他操作 -> 可手动进行session的销毁 -> GC自动清理操作

HttpSessionManager

设置session manager需要通过Leafveingo进行获取leafvein.HttpSessionManager(),还有一些基本的设置是由Leafveingo来进行处理的,以下是列出设置的API:

HttpSessionManager的设置

  //	为方便文档编写设置一个设置为变量进行调用演示
  sessionManager := leafvein.HttpSessionManager()
  
  // cookie设置 Secure 默认 false
  sessionManager.CookieSecure = bool     

  // cookie设置 MaxAge 默认 0             
  sessionManager.CookieMaxAge = int

  // cookie token 生成的 hmac 的哈希类型设置,默认 sha256.New
  // 也可以选择 sha1.New
  sessionManager.CookieTokenHash = func() hash.Hash

  // cookie token 随机数生成的长度,默认 48位
  sessionManager.CookieTokenRandLen = int

  //	cookie token 最大有效时间,默认 300 second
  //	如果超出了有效时间则会自动生成另外一个cookie token,这个不影响HttpSession的使用
  //	只是为了cookie的安全设置的一个机制。
  sessionManager.CookieTokenMaxlifeTime = int32
  
  //	设置CG HttpSession清理的间隔时间,每段时间会进行一次HttpSession的清理
  //	@second	秒单位,大于或等于60m
  sessionManager.SetScanGCTime(second int64)

  //	设置临时HttpSession的最大有效时间,主要是针对第一次请求创建HttpSession所用,
  //  主要为了避免垃圾HttpSession的创建,有些访问了一次并且创建了HttpSession就离
  //	开了,或则Cookie无法写入时,在或者一些人的并发攻击产生大量的HttpSession所使
  //	用的一个机制,在第二次访问的时候就会设置会原来的时间。
  //	创建一个HttpSession最小大约占用136 bit
  //	
  //	避免cookie无法写入时,使用一个临时短暂最大有效时间来控制session的清理。
  //	再第二次请求时如果cookie能够获取得到将还原调用者设置session的最大有效时间。
  //	@second 秒单位,大于或等于60m
  sessionManager.SetTempSessMaxlifeTime(second int32)

  //	设置全局的token key,默认是使用 crypto/rand 进行生成的随机数
  sessionManager.SetGlobalTokenKey(key []byte) 

  //	设置session id的生成规则,默认是SIDTypeRandomUUID随机数的UUID
  //	@ t			SIDTypeRandomUUID or SIDTypeIPUUID
  //	@ urlIPAPi	如果选择SIDTypeRandomUUID可以直接设置为 "" 空。
  //				如果选择SIDTypeIPUUID,可以选择性的设置获取ip的URL地址,传递 "" 空则使用默认地址处理。
  //				也可以根据自己需求,设置url, url必须能直接获取得到网络的IP信息不需要任何解析操作。
  //				由于IPUUID需要连接网络,出现获取不了或解析不了IP的情况下会抛出异常(panic)
  sessionManager.SetSIDType(t SIDType, urlIPApi string) 

  //	HttpSession将要销毁时调用触发的函数
  //	传递的session 是一个复制品,可以根据存储的数据或则session id进行一些业务逻辑操作。
  sessionManager.AddSessionWillInvalidateHandlerFunc(handlerFunc func(session HttpSession))

Leafveingo对session的设置

  //	设置是否开启session进行使用
  leafvein.SetIsUseSession(bool)

  //	首先需要开启session的使用。
  //	设置Leafveingo启动时是否开启自动GC清理无效session的操作。
  //	如果设置为false需要手动进行GC清理操作,即便是手动进行HttpSession
  //	的销毁也无法将HttpSession移除内存。
  //	*leafvein.HttpSessionManager().GC() 手动GC*
  //	建议开启自动清理工作,默认为true
  leafvein.SetIsGCSession(bool)
  
  //	设置默认创建session时最大的有效时间,默认 1800second(30minute)
  leafvein.SetSessionMaxlifeTime(second int32)		

使用HttpSession

HttpSession可以直接使用控制器函数参数直接进行接收

  func (s *SessionController) Session(sess HttpSession) 

也可以手动进行获取,手动获取HttpSession需要使用到HttpContext

  func (s *SessionController) Context(contxt *leafveingo.HttpContext){
  	//	cookie token会在一定时间会自动重置,可以选择重置或则不重置,看需求而定
  	context.Session(true | false)
  }

HttpSession具体的其他操作可以查看下类型接口:

  type HttpSession interface {

  	// 获取session id
  	UID() string    

  	// 根据key name获取session存储的数据                               
  	Get(key string) (interface{}, bool)

  	// 存储session 数据
  	Set(key string, v interface{})

  	// 根据key name删除session数据
  	Delete(key string)               
        
  	// HttpSession 的最后访问时间
  	AccessTime() time.Time       

  	// HttpSession 访问的IP
  	AccessIP() net.IP

  	// HttpSession 最大有效时间获取和设置
  	MaxlifeTime() int32  
  	SetMaxlifeTime(second int32) 

  	// HttpSession 注销,注销后还未从内存中清除,需要等待GC清理。
  	Invalidate() 

  	// 获取HttpSession IP的访问规则,如果一个session出现多个IP就考虑到可能有问题了。
  	// map[<ip string>]<ip count>
  	IPAccessRule() map[string]int

  	// 验证form token,这个可以使用HttpContext调用CheckFormToken()进行验证,
  	// 因为需要获取form token设置的内容
  	CheckFormTokenSignature(signature string) bool 

  	// 获取form token签名,这个也可以使用HttpContext来进行操作,
  	// 具体可以查看HttpContext函数。
  	FormTokenSignature() string

  }

CookieToken机制

HttpSession的存储是存储与服务器中,利用cookie存储session的标识字符,这个标识字符就是利用cookie token的安全机制进行效验成功后才能获取得到正确的session存储对象。

cookie token的作用:

关于session的安全:

  • 由于session cookie token对于IP没有进行验证,如果cookie被真获取了用户信息就会被窃取。关于验证IP有很多争议,由于在手机访问的时候IP会经常的更换或则路由器被重启IP更改,验证都会失效导致用户的体验性非常的差,还有再一个大局域网中外网IP都是相同的,这时验证就等于没有验证的。
  • 对于cookie的劫持Leafveingo已经在Cookie HttpOnly属性中设置为true,这样可以有效的防止javascript读取存储session标识的cookie,不过还会有些安全隐患的。

如何预防呢?目前想到的最有效的机制就是使用Cookie Secure属性的设置,只能使用https访问才能获取得到存储session的cookie。不过Leafveingo对于Cookie Secure默认设置是为false,如果想开启可以设置sessionManager.CookieSecure = true,详细可以查看HttpSessionManager的设置

FormToken机制

为什么使用form token?

form token与cookie token的区别?

  • 两者是不同的关系的,form token主要存储在请求的session中,作用于html form。
  • 对于token生成的规则也不相同,由于已经有一层cookie token的保护,所以生成与cookie token相对简单。

使用form token可以利用HttpContext来进行获取,token每次获取都会更改一次token,对于form token生成验证的token存储是有数量限制的,主要利用了LRU Cache(Least Recently Used)模式进行存储,想修改可以到lv_session.go FORM_TOKEN_SLICE_DEFAULT_LEN的常量中进行修改需要的存储默认最大长度,不过默认10长度的存储数量已经足够用了,毕竟是利用以旧换新的原则进行替换,旧的token验证就会失效,有兴趣可以看下lv_session.go的源码的实现原理。使用LRU Cache主要是为了session存储数据的最小原则,毕竟HttpSession存储再服务器的内存中。

HttpContext提供了几种获取form token的函数:

  // 直接获取token字符串,需要自行操作,获取token进行验证
  func (ctx *HttpContext) FormTokenString() string

  // 返回<input type="hidden" name="formToken" value="xxx" />
  func (ctx *HttpContext) FormTokenHTML() string

  // 利用javseript将token字符串绑定到页面中,可有效防止页面被抓取后获取token
  func (ctx *HttpContext) FormTokenJavascript() string

HttpContext也提供了form token的验证函数:

  // 会以formToken名获取参数进行验证
  func (ctx *HttpContext) CheckFormToken() bool

  // 手动验证,需要自行获取token
  func (ctx *HttpContext) CheckFormTokenByString(token string) bool 

HttpSession销毁通知

HttpSession是有生命的,在最大的有效时间结束后就会被清理出内存,此时为了业务方便,提供了销毁前的通知调用。

具体操作设置:

//	添加一个接收的函数。
//	传递的session是一个复制品,可以根据存储的数据或则session id进行一些业务逻辑操作。
sessionManager.AddSessionWillInvalidateHandlerFunc(handlerFunc func(sess HttpSession))