After designing the data structure of the session, start storing the initial session value

Define the session structure in context.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(a) 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"`
}

Copy the code

The initialization data is then stored in the Session middleware

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))

}
Copy the code

After running the browser, it appears in Redis

The problem is that although the data is stored, the session is restored every time the browser refreshes, which is obviously not what we want. The correct logic should be that the cookie exists and the value can be found in Redis so there is no need to reset.

Modify the code

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))

}
Copy the code

To prevent secondary queries, session results are stored in gin’s 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)

			// Store it in context so that other functions in the current request can manipulate the 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{})},// Here too
	c.Set("_session", session)

	jsonString, _ := json.Marshal(session)

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

}
Copy the code