package http_handler import ( "git.hlsq.asia/mmorpg/service-common/db/redis" "git.hlsq.asia/mmorpg/service-common/utils" "git.hlsq.asia/mmorpg/service-gateway/config" "git.hlsq.asia/mmorpg/service-gateway/internal/global" "github.com/gin-gonic/gin" "github.com/google/uuid" ) var ( scriptLoginSha1 string scriptLogin = ` local at_key = KEYS[1] .. ARGV[1] local rt_key = KEYS[2] .. ARGV[2] local session_key = KEYS[3] .. ARGV[3] redis.call("HSET", at_key, "usn", ARGV[3], "ip", ARGV[6], "ua", ARGV[7], "rt", ARGV[2] ) redis.call("EXPIRE", at_key, tonumber(ARGV[4])) redis.call("HSET", rt_key, "usn", ARGV[3], "ip", ARGV[6], "ua", ARGV[7], "at", ARGV[1] ) redis.call("EXPIRE", rt_key, tonumber(ARGV[5])) local all_rts = redis.call("SMEMBERS", session_key) -- 只允许最大10个会话,多了的随机踢掉 if #all_rts >= 10 then local rk = KEYS[2] .. all_rts[1] local ak = KEYS[1] .. redis.call("HGET", rk, "at") redis.call("DEL", rk) redis.call("DEL", ak) end -- 清理已经失效的会话 for i, rt in ipairs(all_rts) do if redis.call("EXISTS", KEYS[2] .. rt) == 0 then redis.call("SREM", session_key, rt) end end redis.call("SADD", session_key, ARGV[2]) redis.call("EXPIRE", session_key, tonumber(ARGV[5]) + 600) return 1 ` ) func sessionLogin(c *gin.Context, usn int64) (string, string, error) { if scriptLoginSha1 == "" { scriptLoginSha1 = redis.GetClient().ScriptLoad(c, scriptLogin).Val() } at := uuid.New().String() rt := uuid.New().String() err := redis.GetClient().EvalSha( c, scriptLoginSha1, []string{global.KeyGatewayAccessToken, global.KeyGatewayRefreshToken, global.KeyGatewaySession}, at, rt, usn, config.Get().Auth.ShortExpire, config.Get().Auth.LongExpire, c.RemoteIP(), c.GetHeader("User-Agent"), ).Err() if err != nil { return "", "", utils.ErrorsWrap(err) } c.SetCookie("refresh_token", rt, int(config.Get().Auth.LongExpire), "/", ".hlsq.asia", true, true) return at, rt, nil } var ( scriptLogoutSha1 string scriptLogout = ` local rt_key = KEYS[2] .. ARGV[1] local usn = redis.call("HGET", rt_key, "usn") local at = redis.call("HGET", rt_key, "at") local at_key = KEYS[1] .. at local session_key = KEYS[3] .. usn redis.call("DEL", at_key) redis.call("DEL", rt_key) redis.call("SREM", session_key, ARGV[1]) return 1 ` ) func sessionLogout(c *gin.Context, rt string) error { if scriptLogoutSha1 == "" { scriptLogoutSha1 = redis.GetClient().ScriptLoad(c, scriptLogout).Val() } return redis.GetClient().EvalSha( c, scriptLogoutSha1, []string{global.KeyGatewayAccessToken, global.KeyGatewayRefreshToken, global.KeyGatewaySession}, rt, ).Err() }