package middleware import ( "allapp/utils/jwtx" "allapp/utils/pathx" "allapp/utils/redisx" "allapp/utils/response" "context" "strconv" "strings" "github.com/cloudwego/hertz/pkg/app" ) // 私有 key,防止冲突 type ctxKeyUser struct{} // ContextUser 保存用户信息,包括 UserID、DeviceUUID 和当前 SpaceID type ContextUser struct { UserID int64 DeviceUUID string SpaceID int64 } // Auth 中间件,支持 header 中传 spaceid 并校验权限 func Auth() app.HandlerFunc { whitelistPaths := []string{ "/auth/login", "/auth/register", "/auth/refresh/token", } return func(ctx context.Context, c *app.RequestContext) { path := string(c.Request.URI().Path()) if pathx.MatchPath(path, whitelistPaths) { c.Next(ctx) return } // 校验 token token := strings.TrimSpace(string(c.GetHeader("Token"))) verifyToken, flag := jwtx.VerifyToken(token) if !flag { response.Fail(c).Code(response.HttpCode.Unauthorized).Send() c.Abort() return } userID := verifyToken.UserID // 获取 header 中的 spaceid spaceIDStr := strings.TrimSpace(string(c.GetHeader("X-Space-Id"))) spaceID, err := strconv.ParseInt(spaceIDStr, 10, 64) if err != nil || spaceID == 0 { response.Fail(c).Code(response.HttpCode.ErrSpaceRequired).Message("请先选择空间").Send() c.Abort() return } // 判断用户是否在该空间 inSpace, err := redisx.InSpace(ctx, userID, spaceID) if err != nil || !inSpace { response.Fail(c).Code(response.HttpCode.ErrSpaceRequired).Message("无权限访问该空间").Send() c.Abort() return } // 设置 context user := &ContextUser{ UserID: userID, SpaceID: spaceID, } ctx = setContextUser(ctx, user) c.Next(ctx) } } // GetContextUser 从 context 获取用户信息 func GetContextUser(ctx context.Context) *ContextUser { user, ok := ctx.Value(ctxKeyUser{}).(*ContextUser) if !ok || user == nil { return &ContextUser{} } return user } // GetUserID 从 context 获取 user_id func GetUserID(ctx context.Context) int64 { return GetContextUser(ctx).UserID } // GetSpaceID 从 context 获取当前 spaceid func GetSpaceID(ctx context.Context) int64 { return GetContextUser(ctx).SpaceID } // 内部中间件设置 ContextUser func setContextUser(ctx context.Context, user *ContextUser) context.Context { return context.WithValue(ctx, ctxKeyUser{}, user) }