109 lines
2.6 KiB
Go
109 lines
2.6 KiB
Go
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()
|
||
}
|