设计好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中出现
问题出现了,虽然数据存储进去了,但是每刷新一次浏览器就会重新存储一次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))
}
复制代码
有疑问加站长微信联系(非本文作者)