iris-session梳理
入口
api := iris.New()
api.Adapt(gm.NewSession())
session的构造
func NewSession() sessions.Sessions {
db := redis.New(rs.Config{Network: rs.DefaultRedisNetwork,
Addr: config.Instance().Redis.Address,
Password: config.Instance().Redis.Password,
Database: "",
MaxIdle: 0,
MaxActive: 0,
IdleTimeout: rs.DefaultRedisIdleTimeout,
Prefix: "",
MaxAgeSeconds: config.Instance().Redis.MaxAgeSeconds}) // optionally configure the bridge between your redis servermySessions := sessions.New(sessions.Config{Cookie: configs.GetSessionConfig().Cookie, Expires: configs.GetSessionConfig().Expires})
mySessions.UseDatabase(db)
return mySessions
}
MaxAgeSeconds //指的是session在数据库存的有效期
Expires //指的是session的有效期
回到刚才的api.Adapt(gm.NewSession()),装饰器
func (s *sessions) Adapt(frame *iris.Policies) {
// for newcomers this maybe looks strange:
// Each policy is an adaptor too, so they all can contain an Adapt.
// If they contains an Adapt func then the policy is an adaptor too and this Adapt func is called
// by Iris on .Adapt(...)
policy := iris.SessionsPolicy{
Start: s.Start,
Destroy: s.Destroy,
}policy.Adapt(frame)
func (s SessionsPolicy) Adapt(frame *Policies) {if s.Start != nil {frame.SessionsPolicy.Start = s.Start}if s.Destroy != nil {frame.SessionsPolicy.Destroy = s.Destroy}
}
使用
调用context.Session(),获取到session对象
func (ctx *Context) Session() Session {policy := ctx.framework.policies.SessionsPolicyif policy.Start == nil {ctx.framework.Log(DevMode,errSessionsPolicyIsMissing.Format(ctx.RemoteAddr(), ctx.framework.Config.VHost).Error())return nil}if ctx.session == nil {ctx.session = policy.Start(ctx.ResponseWriter, ctx.Request)}return ctx.session
}
如果session==nil,就会调用start
func (s *sessions) Start(res http.ResponseWriter, req *http.Request) iris.Session {var sess iris.SessioncookieValue := GetCookie(s.config.Cookie, req)if cookieValue == "" { // cookie doesn't exists, let's generate a session and add set a cookiesid := SessionIDGenerator(s.config.CookieLength)sess = s.provider.Init(sid, s.config.Expires)cookie := &http.Cookie{} // The RFC makes no mention of encoding url value, so here I think to encode both sessionid key and the value using the safe(to put and to use as cookie) url-encodingcookie.Name = s.config.Cookiecookie.Value = sidcookie.Path = "/"if !s.config.DisableSubdomainPersistence {requestDomain := req.URL.Hostif portIdx := strings.IndexByte(requestDomain, ':'); portIdx > 0 {requestDomain = requestDomain[0:portIdx]}if IsValidCookieDomain(requestDomain) { // RFC2109, we allow level 1 subdomains, but no further // if we have localhost.com , we want the localhost.cos. // so if we have something like: mysubdomain.localhost.com we want the localhost here // if we have mysubsubdomain.mysubdomain.localhost.com we want the .mysubdomain.localhost.com here // slow things here, especially the 'replace' but this is a good and understable( I hope) way to get the be able to set cookies from subdomains & domain with 1-level limitif dotIdx := strings.LastIndexByte(requestDomain, '.'); dotIdx > 0 { // is mysubdomain.localhost.com || mysubsubdomain.mysubdomain.localhost.coms := requestDomain[0:dotIdx] // set mysubdomain.localhost || mysubsubdomain.mysubdomain.localhostif secondDotIdx := strings.LastIndexByte(s, '.'); secondDotIdx > 0 { //is mysubdomain.localhost || mysubsubdomain.mysubdomain.localhosts = s[secondDotIdx+1:] // set to localhost || mysubdomain.localhost} // replace the s with the requestDomain before the domain's siffuxsubdomainSuff := strings.LastIndexByte(requestDomain, '.')if subdomainSuff > len(s) { // if it is actual exists as subdomain suffixrequestDomain = strings.Replace(requestDomain, requestDomain[0:subdomainSuff], s, 1) // set to localhost.com || mysubdomain.localhost.com}} // finally set the .localhost.com (for(1-level) || .mysubdomain.localhost.com (for 2-level subdomain allow)cookie.Domain = "." + requestDomain // . to allow persistence}}cookie.HttpOnly = true // 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 secondsif s.config.Expires >= 0 {if s.config.Expires == 0 { // unlimited lifecookie.Expires = CookieExpireUnlimited} else { // > 0cookie.Expires = time.Now().Add(s.config.Expires)}cookie.MaxAge = int(cookie.Expires.Sub(time.Now()).Seconds())} // encode the session id cookie client value right before send it.cookie.Value = s.encodeCookieValue(cookie.Value)AddCookie(cookie, res)} else {cookieValue = s.decodeCookieValue(cookieValue)sess = s.provider.Read(cookieValue, s.config.Expires)}return sess
}
再设置cookie.Domain的时候,req.URL作为服务端的时候,是没有Host信息的,所以cookie.Domain 会默认空串。
再看s.provider.Init
// Init creates the session and returns it
func (p *provider) Init(sid string, expires time.Duration) iris.Session {
newSession := p.newSession(sid, expires)
p.mu.Lock()
p.sessions[sid] = newSession
p.mu.Unlock()
return newSession
}
init的时候做了两件事:
1.newSession
2.将session存到p.sessions里面
// newSession returns a new session from sessionid
func (p *provider) newSession(sid string, expires time.Duration) *session {sess := &session{sid: sid,provider: p,values: p.loadSessionValues(sid),flashes: make(map[string]*flashMessage),}if expires > 0 { // if not unlimited life duration and no -1 (cookie remove action is based on browser's session)time.AfterFunc(expires, func() { // the destroy makes the check if this session is exists then or not, // this is used to destroy the session from the server-side also // it's good to have here for security reasons, I didn't add it on the gc function to separate its actionp.Destroy(sid)})}return sess
}
这里可以看到在配置文件中设置的expire 是用来起了一个定时任务,之后删掉这个session
func (p *provider) Destroy(sid string) {p.mu.Lock()if sess, found := p.sessions[sid]; found {sess.values = nilsess.flashes = nildelete(p.sessions, sid)p.updateDatabases(sid, nil)}p.mu.Unlock()
}
destory的时候:
如果没有删除:
1.从p.sessions里面删除
2.更新到数据库
iris-session梳理相关推荐
- 使用 GitHub Actions 在 EKS 上部署 InterSystems IRIS 解决方案
假设你想了解 InterSystems 在数据分析方面能提供什么. 你研究了理论,现在想要进行一些实践. 幸运的是,InterSystems 提供了一个项目:Samples BI,其中包含了一些很好的 ...
- 2022面试200题目和答案分布式+微服务+MYSQL+Redis+JVM+Spring
200题目和答案分布式+微服务+MYSQL+Redis+JVM+Spring等等 带图MD在资源https://download.csdn.net/download/m0_47987937/86509 ...
- session多服务器共享的方案梳理
默认情况下,php的session文件是保存在磁盘文件中.在php.ini配置文件中的配置项如下: session.save_handler = files session.save_path = & ...
- kafka session.timeout.ms 是指消费一条数据的时间?_干货 | Kafka 内核知识梳理,附思维导图...
前面我们已经分享过几篇Kafka的文章,最近简单梳理了下Kafka内核相关的知识,涵盖了Kafka架构总结,副本机制,控制器,高水位机制,日志或消息存储,消息发送与消费机制等方面知识.文末含对应的Ka ...
- Golang框架选型比较: goframe, beego, iris和gin
由于工作需要,这些年来也接触了不少的开发框架,Golang的开发框架比较多,不过基本都是Web"框架"为主.这里稍微打了个引号,因为大部分"框架"从设计和功能定 ...
- 负载均衡中使用 Redis 实现共享 Session
最近在研究Web架构方面的知识,包括数据库读写分离,Redis缓存和队列,集群,以及负载均衡(LVS),今天就来先学习下我在负载均衡中遇到的问题,那就是session共享的问题. 一.负载均衡 负载均 ...
- session传递参数_分布式 Session 之 Spring Session 架构与设计
作者 | 李增光 杏仁后端工程师.「只有变秃,才能变强!」 前言 开始进行 Web 开发时,我们可能会遇到这样的情况,当服务器重启之后,之前的登录状态会失效需要重新登录.又或者你的应用程序部署了不止 ...
- 梳理消息队列 MQ/JMS/Kafka
是不是平常听到说消息队列啊,JMS啊,MQ啊 .kafka啊巴啦啦的一堆术语,听不懂?关系混乱?今天就让我们来一起来看看他们都是什么吧. 1消息队列介绍 首先举个收快递的栗子,传统的收快递,快递小哥把 ...
- R语言相关关系可视化函数梳理(附代码)
来源:R语言中文社区 作者:赵镇宁 本文约3177字,建议阅读6分钟. 本文为你介绍R语言相关关系可视化的函数进行了初步梳理,大家可根据个人需求及函数功能择优选择. 当考察多个变量间的相关关系时,通常 ...
最新文章
- Github上如何在组织中创建代码仓库,并如何授予该组织中某个小组权限?
- 运用C#生成docx格式的报表
- Python 技术篇-容易被忽略的尾差问题
- research proposal under dr. wang
- easyui combo自动高度(下拉框空白问题)
- 一个“登录框“引发的安全问题
- 补充小知识:文件句柄与文件标识符
- 考驾照重点科目的关键考试技巧
- id,rowid,rownum 区别
- linux批量筛选序列变异位点,使用bedtools获取指定坐标上下游的序列
- 使用青云主机的GPU主机教程(不完整版)
- MAC ideaeclipse快捷键--笔记
- [收藏] 将 DTS 用于业务智能解决方案的最佳实践
- C++ HOOK实现全局键盘钩子的详细过程
- 华为三层交换机配置方法实例
- 心随风飞扬,仍存一线牵~
- 使用gdb调试出现 No debugging symbols found in a.out
- 利用Python读取Excel表格并可视化
- 关闭只为更好,耐克NRC退出中国市场,新一代“本地版”即将推出
- 可以免费部署自己个人主页的一个神仙网站vercel