Skip to content

Latest commit

 

History

History
102 lines (79 loc) · 3.81 KB

README.md

File metadata and controls

102 lines (79 loc) · 3.81 KB

clerk-gin-middleware

This is an example trying to use the provided Clerk middleware, specifically RequireSessionV2, as a gin middleware function (gin.HandlerFunc).

Run the example:

  • go build ./...
  • CLERK_DEVELOPMENT_SECRET_KEY=sk_test_redacted go run main.go Use your own clerk key.

There are three endpoints.

  • /livez is a health check
  • /user fetches the user by directly parsing the token from the headers, without using any middleware
  • /user-with-middleware is wrapped in middleware and tries to read the session out of the request context

This is the example that I use.

curl --location --request GET 'http://localhost:4242/user-with-middleware' \
--header 'Authorization: Bearer <token>'

I set the leeway very high so the token I'm passing continues to work and I don't need to refresh it.

For http://localhost:4242/user, it all works find and it's able to retrieve the user:

[GIN] 2023/02/03 - 11:32:54 | 200 |  222.940625ms |       127.0.0.1 | GET      "/user"

and it returns:

{"firstName":"Hanna","lastName":"Lee"}

However, for http://localhost:4242/user-with-middleware, it logs this:

found session in noop handler
did not find session in middleware


2023/02/03 11:27:46 [Recovery] 2023/02/03 - 11:27:46 panic recovered:
GET /user-with-middleware HTTP/1.1
Host: localhost:4242
Accept: */*
Authorization: *
User-Agent: curl/7.84.0


runtime error: invalid memory address or nil pointer dereference
/opt/homebrew/Cellar/go/1.19.5/libexec/src/runtime/panic.go:260 (0x1046034b7)
	panicmem: panic(memoryError)
/opt/homebrew/Cellar/go/1.19.5/libexec/src/runtime/signal_unix.go:835 (0x10461b227)
	sigpanic: panicmem()
/Users/hannalee/sandbox/clerk-gin-middleware/main.go:73 (0x1048f9320)
	main.func3: user, err := clerkClient.Users().Read(clerkSessionClaims.Claims.Subject)
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x1048f9d0b)
	(*Context).Next: c.handlers[c.index](c)
/Users/hannalee/sandbox/clerk-gin-middleware/main.go:139 (0x1048f9ccc)
	clerkMiddlewareAttempt2.func2: c.Next()
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x1048f3c6b)
	(*Context).Next: c.handlers[c.index](c)
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/recovery.go:101 (0x1048f3c4c)
	CustomRecoveryWithWriter.func1: c.Next()
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x1048f2eeb)
	(*Context).Next: c.handlers[c.index](c)
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/logger.go:240 (0x1048f2ec8)
	LoggerWithConfig.func1: c.Next()
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x1048f2073)
	(*Context).Next: c.handlers[c.index](c)
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/gin.go:616 (0x1048f1d58)
	(*Engine).handleHTTPRequest: c.Next()
/Users/hannalee/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/gin.go:572 (0x1048f1ab3)
	(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/opt/homebrew/Cellar/go/1.19.5/libexec/src/net/http/server.go:2947 (0x1047cf813)
	serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/opt/homebrew/Cellar/go/1.19.5/libexec/src/net/http/server.go:1991 (0x1047cc74f)
	(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/opt/homebrew/Cellar/go/1.19.5/libexec/src/runtime/asm_arm64.s:1172 (0x104634ef3)
	goexit: MOVD	R0, R0	// NOP

Essentially, I believe the issue is that if the Clerk middleware adds to the request context, it should modify the request context. Instead, it is creating a new one (https://github.com/clerkinc/clerk-sdk-go/blob/main/clerk/middleware_v2.go#L135).

Instead of:

ctx := context.WithValue(r.Context(), ActiveSessionClaims, claims)
next.ServeHTTP(w, r.WithContext(ctx))
return

perhaps we could do:

ctx := context.WithValue(r.Context(), ActiveSessionClaims, claims)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
return