使用gin封装一个web脚手架(六):实现session(中)

一位不愿意透露姓名的杨先生 · · 360 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

设计好session的数据结构后开始存放初始session值

先在context.go中定义好session的结构体

package context

//context/context.go

import (
	"github.com/gin-gonic/gin"
	"strings"
)

type Context struct {
	*gin.Context
}

type HandlerFunc func(*Context)

func (c *Context) Domain() string {

	return c.Request.Host[:strings.Index(c.Request.Host, ":")]
}

type Session struct {
	Cookie      string                 `json:"cookie"`
	ExpireTime  int64                  `json:"expire_time"`
	SessionList map[string]interface{} `json:"session_list"`
}

复制代码

接下来在session中间件中存储初始化数据

package session

import (
	context2 "context"
	"encoding/json"
	uuid "github.com/satori/go.uuid"
	"myGin/context"
	"myGin/redis"
	"time"
)

var cookieName = "my_gin"

var lifeTime = 3600

func Session(c *context.Context) {

	sessionKey := uuid.NewV4().String()

	c.SetCookie(cookieName, sessionKey, lifeTime, "/", c.Domain(), false, true)

	session := context.Session{
		Cookie:      sessionKey,
		ExpireTime:  time.Now().Unix() + int64(lifeTime),
		SessionList: make(map[string]interface{}),
	}

	jsonString, _ := json.Marshal(session)

	redis.Client().Set(context2.TODO(), sessionKey, jsonString, time.Second*time.Duration(lifeTime))

}
复制代码

运行浏览器后,在redis中出现

image.png

问题出现了,虽然数据存储进去了,但是每刷新一次浏览器就会重新存储一次session,这显然不是我们想要的。正确的逻辑应该是,cookie存在并且能够在redis中找到这个值就不需要重新设置了。

修改一下代码

package session

import (
	context2 "context"
	"encoding/json"
	uuid "github.com/satori/go.uuid"
	"myGin/context"
	"myGin/redis"
	"time"
)

var cookieName = "my_gin"

var lifeTime = 3600

func Session(c *context.Context) {

	cookie, err := c.Cookie(cookieName)

	if err == nil {

		sessionString, err := redis.Client().Get(context2.TODO(), cookie).Result()

		if err == nil {

			var session context.Session

			json.Unmarshal([]byte(sessionString), &session)

			return
		}

	}

	sessionKey := uuid.NewV4().String()

	c.SetCookie(cookieName, sessionKey, lifeTime, "/", c.Domain(), false, true)

	session := context.Session{
		Cookie:      sessionKey,
		ExpireTime:  time.Now().Unix() + int64(lifeTime),
		SessionList: make(map[string]interface{}),
	}

	jsonString, _ := json.Marshal(session)

	redis.Client().Set(context2.TODO(), sessionKey, jsonString, time.Second*time.Duration(lifeTime))

}
复制代码

为了防止二次查询,将session结果存储到gin的context中

package session

import (
	context2 "context"
	"encoding/json"
	uuid "github.com/satori/go.uuid"
	"myGin/context"
	"myGin/redis"
	"time"
)

var cookieName = "my_gin"

var lifeTime = 3600

func Session(c *context.Context) {

	cookie, err := c.Cookie(cookieName)

	if err == nil {

		sessionString, err := redis.Client().Get(context2.TODO(), cookie).Result()

		if err == nil {

			var session context.Session

			json.Unmarshal([]byte(sessionString), &session)

			//存储到context中,方便当前请求中的其他函数好操作session
			c.Set("_session", session)

			return
		}

	}

	sessionKey := uuid.NewV4().String()

	c.SetCookie(cookieName, sessionKey, lifeTime, "/", c.Domain(), false, true)

	session := context.Session{
		Cookie:      sessionKey,
		ExpireTime:  time.Now().Unix() + int64(lifeTime),
		SessionList: make(map[string]interface{}),
	}

	//这里也要
	c.Set("_session", session)

	jsonString, _ := json.Marshal(session)

	redis.Client().Set(context2.TODO(), sessionKey, jsonString, time.Second*time.Duration(lifeTime))

}
复制代码

有疑问加站长微信联系(非本文作者)

本文来自:掘金

感谢作者:一位不愿意透露姓名的杨先生

查看原文:使用gin封装一个web脚手架(六):实现session(中)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

360 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传