feat: 添加数据库缓存和多租户支持

This commit is contained in:
2026-03-17 16:09:19 +08:00
parent b9acc7bc18
commit 1cb6786dcb
3 changed files with 567 additions and 65 deletions

View File

@@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/os/gtime"
"net"
"reflect"
"sort"
@@ -18,6 +17,7 @@ import (
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"github.com/tiger1103/gfast-token/gftoken"
)
@@ -66,67 +66,71 @@ func GetMonthToday(t time.Time, month int) time.Time {
return target.AddDate(0, 0, t.Day()-1)
}
func GetUserInfo(ctx context.Context) (user beans.User, err error) {
// 检查context是否已取消
select {
case <-ctx.Done():
return user, ctx.Err()
default:
func GetUserInfo(ctx context.Context) (user *beans.User, err error) {
// 1. 优先从 context 中获取
if !g.IsNil(ctx.Value("user")) {
err = gconv.Struct(ctx.Value("user"), &user)
if err != nil {
return user, gerror.Wrap(err, "用户信息转换失败")
}
return
}
if !g.IsNil(ctx.Value("id")) || !g.IsNil(ctx.Value("userName")) || !g.IsNil(ctx.Value("tenantId")) {
user.UserId = ctx.Value("id")
user.UserName = ctx.Value("userName")
user.TenantId = ctx.Value("tenantId")
} else {
redisAddr := g.Cfg().MustGet(ctx, "redis.default.address").String()
gft := gftoken.NewGfToken(
gftoken.WithCacheKey("gfToken:"),
gftoken.WithTimeout(20),
gftoken.WithMaxRefresh(10),
gftoken.WithMultiLogin(true),
//gftoken.WithExcludePaths(g.SliceStr{"/excludeDemo"}),
gftoken.WithGRedisConfig(&gredis.Config{
Address: redisAddr,
Db: 1,
}))
var data *gftoken.CustomClaims
if !g.IsNil(ctx.Value("token")) {
var tokenData *gftoken.TokenData
tokenData, _, err = gft.GetTokenData(ctx, ctx.Value("token").(string))
// 2. 从请求头中获取gateway 转发时设置)
if req := g.RequestFromCtx(ctx); req != nil {
userInfoHeader := req.Header.Get("X-User-Info")
if userInfoHeader != "" {
err = gconv.Struct(userInfoHeader, &user)
if err != nil {
return user, gerror.Wrap(err, "token 解析失败")
}
var code int
if data, code = gft.IsNotExpired(tokenData.JwtToken); code != gftoken.JwtTokenOK {
return user, gerror.New("token jwt 解析失败")
}
} else if g.RequestFromCtx(ctx) != nil {
// 解析 token
data, err = gft.ParseToken(g.RequestFromCtx(ctx))
if err != nil {
return user, gerror.Wrap(err, "token 解析失败")
return user, gerror.Wrap(err, "请求头用户信息解析失败")
}
return
}
// 检查 data 是否为 nil
if data == nil {
return user, gerror.New("token 数据为空")
}
// 检查 data.Data 是否为 nil
if data.Data == nil {
g.Log().Errorf(ctx, "data.Data 为空")
return user, gerror.New("用户信息为空")
}
dataMap := gconv.Map(data.Data)
user.UserId = dataMap["id"]
user.UserName = dataMap["userName"]
user.TenantId = dataMap["tenantId"]
}
if g.IsNil(user.UserId) && g.IsNil(user.UserName) && g.IsNil(user.TenantId) {
return user, gerror.New("租户信息为空")
// 3. 从 token 解析
redisAddr := g.Cfg().MustGet(ctx, "redis.default.address").String()
gft := gftoken.NewGfToken(
gftoken.WithCacheKey("gfToken:"),
gftoken.WithTimeout(20),
gftoken.WithMaxRefresh(10),
gftoken.WithMultiLogin(true),
//gftoken.WithExcludePaths(g.SliceStr{"/excludeDemo"}),
gftoken.WithGRedisConfig(&gredis.Config{
Address: redisAddr,
Db: 1,
}))
var data *gftoken.CustomClaims
if !g.IsNil(ctx.Value("token")) {
var tokenData *gftoken.TokenData
tokenData, _, err = gft.GetTokenData(ctx, ctx.Value("token").(string))
if err != nil {
return user, gerror.Wrap(err, "ctx token 解析失败")
}
var code int
if data, code = gft.IsNotExpired(tokenData.JwtToken); code != gftoken.JwtTokenOK {
return user, gerror.New("token jwt 解析失败")
}
} else if g.RequestFromCtx(ctx) != nil {
// 解析 token
data, err = gft.ParseToken(g.RequestFromCtx(ctx))
if err != nil {
return user, gerror.Wrap(err, "token 解析失败")
}
}
// 检查 data 是否为 nil
if data == nil {
return user, gerror.New("token 数据为空")
}
// 检查 data.Data 是否为 nil
if data.Data == nil {
return user, gerror.New("用户信息为空")
}
err = gconv.Struct(data.Data, &user)
if err != nil {
return user, gerror.Wrap(err, "用户信息转换失败")
}
return
}