1 Star 0 Fork 0

曾广宇/mxx-core-v2

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
gin_mysql_store.go 4.72 KB
一键复制 编辑 原始数据 按行查看 历史
曾广宇 提交于 2024-06-13 14:11 +08:00 . 升级
package mweb
import (
"encoding/base32"
"errors"
"gitee.com/dennis-mxx/mxx-core-v2/mutil"
"github.com/goccy/go-json"
"github.com/gorilla/securecookie"
"github.com/gorilla/sessions"
"net/http"
"strings"
"time"
"xorm.io/xorm"
)
type EntitySessions struct {
ID int64 `xorm:"pk id autoincr bigint(20) notnull comment('id') "`
SessionId string `xorm:"varchar(255) key('session_id') comment('sessionId')" json:"sessionId"`
ServerName string `xorm:"varchar(255) comment('服务名称')" json:"serverName"`
ContentType string `xorm:"varchar(1000) comment('请求头')" json:"ContentType"`
Value string `xorm:"varchar(500) comment('值')" json:"value"`
Expire *time.Time `xorm:"varchar(500) comment('过期时间')" json:"expire"`
CreateTime *time.Time `xorm:"created varchar(500) comment('创建时间')" json:"CreateTime"`
UpdateTime *time.Time `xorm:"updated created varchar(500) comment('修改时间')" json:"UpdateTime"`
}
func (ce *EntitySessions) TableName() string {
return "tb_sessions"
}
type MysqlStore struct {
Options *sessions.Options
MySqlClient *xorm.Engine
Codecs []securecookie.Codec
serverName string
}
func NewMysqlStore(mysqlClient *xorm.Engine, prefix string, keyPairs ...[]byte) *MysqlStore {
return &MysqlStore{
Codecs: securecookie.CodecsFromPairs(keyPairs...),
Options: &sessions.Options{
Path: "/",
MaxAge: 86400 * 30,
},
MySqlClient: mysqlClient,
serverName: prefix,
}
}
func (domain *MysqlStore) Get(r *http.Request, name string) (*sessions.Session, error) {
return sessions.GetRegistry(r).Get(domain, name)
}
func (domain *MysqlStore) New(r *http.Request, name string) (*sessions.Session, error) {
session := sessions.NewSession(domain, name)
opts := *domain.Options
session.Options = &opts
session.IsNew = true
var err error
if c, errCookie := r.Cookie(name); errCookie == nil {
err = securecookie.DecodeMulti(name, c.Value, &session.ID, domain.Codecs...)
if err == nil {
err = domain.loadValue(session.ID, &session.Values, r.Header.Get("Content-Type"))
if err == nil {
session.IsNew = false
}
}
}
return session, err
}
func (domain *MysqlStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
if session.Options.MaxAge <= 0 {
if err := domain.delete(session); err != nil {
return err
}
http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options))
return nil
}
if session.ID == "" || session.IsNew {
// Because the ID is used in the filename, encode it to
// use alphanumeric characters only.
session.ID = strings.TrimRight(
base32.StdEncoding.EncodeToString(
securecookie.GenerateRandomKey(32)), "=")
}
if err := domain.save(r, session); err != nil {
return err
}
encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
domain.Codecs...)
if err != nil {
return err
}
http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options))
return nil
}
func (domain *MysqlStore) loadValue(sessionId string, dest *map[interface{}]interface{}, contentType string) error {
entity := &EntitySessions{}
err := domain.MySqlClient.Where(map[string]string{
"session_id": sessionId,
"server_name": domain.serverName,
"content_type": contentType,
}).Find(entity)
if err != nil {
return err
}
if entity != nil {
if entity.Expire.Unix() < mutil.DateUtil.NowDateTime().Unix() {
domain.MySqlClient.ID(entity.ID).Delete()
return errors.New("session is overtime")
}
if entity.Value != "" {
err := json.Unmarshal([]byte(entity.Value), &dest)
if err != nil {
return err
}
}
return nil
}
return errors.New("session is not found")
}
func (domain *MysqlStore) delete(session *sessions.Session) error {
_, err := domain.MySqlClient.Where(map[string]string{"session_id": session.ID}).Delete()
return err
}
func (domain *MysqlStore) save(r *http.Request, session *sessions.Session) error {
newMap := make(map[string]interface{})
for k, v := range session.Values {
if ks, b := k.(string); b {
newMap[ks] = v
} else {
panic("unsupported not string key")
}
}
if b, err := json.Marshal(&newMap); err == nil {
v := string(b)
e := mutil.DateUtil.NowDateTime().Add(time.Duration(session.Options.MaxAge) * time.Second)
if session.IsNew {
_, err := domain.MySqlClient.InsertOne(&EntitySessions{
SessionId: session.ID,
ServerName: domain.serverName,
ContentType: r.Header.Get("Content-Type"),
Value: v,
Expire: &e,
})
return err
} else {
_, err := domain.MySqlClient.Where(map[string]string{
"session_id": session.ID,
"server_name": domain.serverName,
}).Cols("expire", "value").Update(EntitySessions{Expire: &e, Value: v})
return err
}
} else {
return err
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/dennis-mxx/mxx-core-v2.git
git@gitee.com:dennis-mxx/mxx-core-v2.git
dennis-mxx
mxx-core-v2
mxx-core-v2
v0.4.74

搜索帮助