Rest Go Gin设置和从中间件访问上下文值

Rest Go Gin设置和从中间件访问上下文值,rest,go,jwt,handler,go-gin,Rest,Go,Jwt,Handler,Go Gin,我尝试在中间件中设置我的用户上下文,然后尝试检查用户是否拥有其他处理程序函数的权限。但由于某种原因,当我试图从上下文访问用户时,它返回为nils。中间件代码似乎正在工作,当我传递一个有效的jwt令牌时,它显示用户正在中间件函数的上下文中设置。但只要我点击getCurrentUser函数,它就会显示为零 代码如下: 中间件 // Middleware wraps the request with auth middleware func Middleware(path string, sc *cf

我尝试在中间件中设置我的用户上下文,然后尝试检查用户是否拥有其他处理程序函数的权限。但由于某种原因,当我试图从上下文访问用户时,它返回为nils。中间件代码似乎正在工作,当我传递一个有效的jwt令牌时,它显示用户正在中间件函数的上下文中设置。但只要我点击getCurrentUser函数,它就会显示为零

代码如下: 中间件

// Middleware wraps the request with auth middleware
func Middleware(path string, sc *cfg.Server, orm *orm.ORM) gin.HandlerFunc {
    logger.Info("[Auth.Middleware] Applied to path: ", path)
    return gin.HandlerFunc(func(c *gin.Context) {
        t, err := ParseToken(c, sc)
        if err != nil {
            authError(c, err)
        } else {
            if claims, ok := t.Claims.(jwt.MapClaims); ok {
                if claims["exp"] != nil {
                    issuer := claims["iss"].(string)
                    userid := claims["jti"].(string)
                    email := claims["email"].(string)
                    if claims["aud"] != nil {
                        audiences := claims["aud"].(interface{})
                        logger.Warnf("\n\naudiences: %s\n\n", audiences)
                    }
                    if claims["alg"] != nil {
                        algo := claims["alg"].(string)
                        logger.Warnf("\n\nalgo: %s\n\n", algo)
                    }
                    if user, err := orm.FindUserByJWT(email, issuer, userid); err != nil {
                        authError(c, ErrForbidden)
                    } else {
                        if user != nil {
                            c.Request = addToContext(c, consts.ProjectContextKeys.UserCtxKey, user)
                            logger.Debug("User: ", user.ID)
                        }
                        c.Next()
                    }
                } else {
                    authError(c, ErrMissingExpField)
                }
            } else {
                authError(c, err)
            }
        }
    })
}
路线

// User routes
func User(sc *cfg.Server, r *gin.Engine, orm *orm.ORM) error {
    // OAuth handlers
    mw := auth.Middleware(sc.VersionedEndpoint("/user/:id"), sc, orm)
    g := r.Group(sc.VersionedEndpoint("/user"))
    g.Use(mw)
    g.GET("/:id", mw, user.Get(orm))
    g.PUT("/:id", mw, user.Update(orm))
    g.POST("/", user.Create(orm))

    return nil
}
处理者

func Get(orm *orm.ORM) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cu := getCurrentUser(ctx)
        if ok, err := cu.HasPermission(consts.Permissions.Create, consts.EntityNames.Users); !ok || err != nil {
            ctx.String(http.StatusUnauthorized, "BAD")
        }
    }
}

addToContext:

func addToContext(c *gin.Context, key consts.ContextKey, value interface{}) *http.Request {
    return c.Request.WithContext(context.WithValue(c.Request.Context(), key, value))
}
getCurrentUser:

func getCurrentUser(ctx context.Context) *dbm.User {
    cu := ctx.Value(utils.ProjectContextKeys.UserCtxKey).(*dbm.User)
    logger.Debugf("currentUser: %s - %s", cu.Email, cu.ID)
    return cu
}

问题是,您将用户存储在一个上下文中,但随后尝试从另一个上下文中检索用户。值
*gin.Context
和值
*gin.Context.Request.Context
是两个独立的上下文值

您正在使用请求的上下文存储用户:

c.Request.WithContext(context.WithValue(c.Request.Context(), key, value))
func getCurrentUser(ctx context.Context) *dbm.User {
    cu := ctx.Value(utils.ProjectContextKeys.UserCtxKey).(*dbm.User)
    // ...

func Get(orm *orm.ORM) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cu := getCurrentUser(ctx) // here you're passing *gin.Context to the function.
        // ...
然后使用gin上下文检索用户:

c.Request.WithContext(context.WithValue(c.Request.Context(), key, value))
func getCurrentUser(ctx context.Context) *dbm.User {
    cu := ctx.Value(utils.ProjectContextKeys.UserCtxKey).(*dbm.User)
    // ...

func Get(orm *orm.ORM) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cu := getCurrentUser(ctx) // here you're passing *gin.Context to the function.
        // ...
因此,要修复该问题,请更改传递给
getCurrentUser
调用的值:

func Get(orm *orm.ORM) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cu := getCurrentUser(ctx.Request.Context())
        if ok, err := cu.HasPermission(consts.Permissions.Create, consts.EntityNames.Users); !ok || err != nil {
            ctx.String(http.StatusUnauthorized, "BAD")
        }
    }
}

问题是,您将用户存储在一个上下文中,但随后尝试从另一个上下文中检索用户。值
*gin.Context
和值
*gin.Context.Request.Context
是两个独立的上下文值

您正在使用请求的上下文存储用户:

c.Request.WithContext(context.WithValue(c.Request.Context(), key, value))
func getCurrentUser(ctx context.Context) *dbm.User {
    cu := ctx.Value(utils.ProjectContextKeys.UserCtxKey).(*dbm.User)
    // ...

func Get(orm *orm.ORM) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cu := getCurrentUser(ctx) // here you're passing *gin.Context to the function.
        // ...
然后使用gin上下文检索用户:

c.Request.WithContext(context.WithValue(c.Request.Context(), key, value))
func getCurrentUser(ctx context.Context) *dbm.User {
    cu := ctx.Value(utils.ProjectContextKeys.UserCtxKey).(*dbm.User)
    // ...

func Get(orm *orm.ORM) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cu := getCurrentUser(ctx) // here you're passing *gin.Context to the function.
        // ...
因此,要修复该问题,请更改传递给
getCurrentUser
调用的值:

func Get(orm *orm.ORM) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cu := getCurrentUser(ctx.Request.Context())
        if ok, err := cu.HasPermission(consts.Permissions.Create, consts.EntityNames.Users); !ok || err != nil {
            ctx.String(http.StatusUnauthorized, "BAD")
        }
    }
}

添加
addToContext
getCurrentUser
的代码。添加了这些函数添加
addToContext
getCurrentUser
的代码。添加了这些函数