huma icon indicating copy to clipboard operation
huma copied to clipboard

Forwarding headers through the middleware not working

Open spa5k opened this issue 1 year ago • 5 comments
trafficstars

So I have a small middleware that reads the cookie and writes a "User-Id" header through the context, but when I try to read the same header in the handler or in the next middleware, it remains empty

func UserAuthenticationMiddleware(tokenService *token.Manager) func(ctx huma.Context, next func(huma.Context)) {
	return func(ctx huma.Context, next func(huma.Context)) {
		tokenCookie, err := huma.ReadCookie(ctx, "review_hq_token")
		...
		userId, err := tokenService.VerifyToken(tokenCookie.Value)
		if err != nil {
			ctx.SetStatus(401)
			ctx.BodyWriter().Write([]byte(err.Error()))
			return
		}

		ctx.SetHeader("User-Id", userId)

		ctx = huma.WithValue(ctx, "User-Id", userId)

		next(ctx)
	}
}
huma.Register(api, huma.Operation{
		Path:        path,
		Method:      "POST",
		Tags:        []string{"Review"},
		OperationID: "create-review",
		Middlewares: huma.Middlewares{
			middleware.UserAuthenticationMiddleware(tokenService),
			func(ctx huma.Context, next func(huma.Context)) {
				// This is empty
				println("userid from middleware", ctx.Header("User-Id"))
			},
		},
	}, func(ctx context.Context, i *CreateReviewRequest) (*createReviewResponse, error) {
		// first is empty, second works
		println("reviewUserID", i.UserId)
		println("reviewUserID", ctx.Value("User-Id").(string))

Passing values through context is working as expected.

spa5k avatar Apr 21 '24 09:04 spa5k

It's because huma.Context.Header reads request headers, but huma.Context.SetHeader sets response headers.

x-user avatar Apr 21 '24 13:04 x-user

So this set header is only for response? I can't update the headers of the request when it reaches Middleware?

spa5k avatar Apr 21 '24 13:04 spa5k

Yes. At least for now you can only do this in router own middleware.

x-user avatar Apr 21 '24 13:04 x-user

@spa5k if you must override headers in router-agnostic middleware, you can create your own struct which wraps huma.Context and override yourStruct.Header(name string) string to return the values you want. Otherwise, like @x-user says you can do this in the underlying router's own middlewares.

danielgtaylor avatar Apr 22 '24 16:04 danielgtaylor

imo, it should forward the headers naturally, how do other framework/languages handle it?

spa5k avatar Apr 30 '24 09:04 spa5k