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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
go复制代码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中间件中存储初始化数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
go复制代码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中找到这个值就不需要重新设置了。

修改一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
go复制代码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中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
go复制代码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))

}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%