-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Guide] - Validate Auth token using Fiber #281
Comments
I tried something like this, but got main.go app.Use(
healthcheck.New(),
logger.New(),
cors.New(),
middleware.AuthMiddleware(),
) auth_middleware.go import (
"fmt"
"net/http"
"os"
"strings"
"github.com/clerk/clerk-sdk-go/v2"
"github.com/clerk/clerk-sdk-go/v2/jwt"
"github.com/gofiber/fiber/v2"
"github.com/imchivaa/mindful-backend/responses"
)
func AuthMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
clerk.SetKey(os.Getenv("CLERK_SECRET_KEY"))
headerAuth := c.Request().Header.Peek("Authorization")
authTokenBearer := string(headerAuth[:])
authToken := strings.TrimPrefix(authTokenBearer, "Bearer ")
_, err := jwt.Verify(c.Context(), &jwt.VerifyParams{
Token: authToken,
})
fmt.Println("err: " + err.Error())
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: "unauthorized"})
}
return c.Next()
}
} |
tried a diff way, i can see the Context have the header Authorization with the Bearer value, but func main() {
app := fiber.New()
app.Use(
healthcheck.New(),
logger.New(),
cors.New(),
withHeaderAuthorizationHandlerMiddleware(),
)
routes.TodoRoute(app)
app.Listen(os.Getenv("HOST"))
}
func withHeaderAuthorizationHandlerMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
_, ok := clerk.SessionClaimsFromContext(c.Context())
if !ok {
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: "unauthorized"})
}
return c.Next()
}
} |
Okay, i got it working, but not sure if this is the best practice or not. import (
"net/http"
"os"
"strings"
"mindful/responses"
"mindful/routes"
"github.com/clerk/clerk-sdk-go/v2"
clerkInc "github.com/clerkinc/clerk-sdk-go/clerk"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/healthcheck"
"github.com/gofiber/fiber/v2/middleware/logger"
)
// Main entry point of the GoFiber application
func main() {
// Initialize Fiber
app := fiber.New()
// Apply Clerk secret key
clerk.SetKey(os.Getenv("CLERK_SECRET_KEY"))
// Apply some middlewares
app.Use(
healthcheck.New(),
logger.New(),
cors.New(),
authorizationMiddleware(),
)
// Register all our routes
routes.TodoRoute(app)
// Start the application
app.Listen(os.Getenv("HOST"))
}
func authorizationMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
client, _ := clerkInc.NewClient(os.Getenv("CLERK_SECRET_KEY"))
headerAuth := c.Request().Header.Peek("Authorization")
authTokenBearer := string(headerAuth[:])
authToken := strings.TrimPrefix(authTokenBearer, "Bearer ")
sessClaims, err := client.VerifyToken(authToken)
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: "unauthorized"})
}
_, err = client.Users().Read(sessClaims.Claims.Subject)
if err != nil {
panic(err)
}
return c.Next()
}
} |
Hi @imchivaa, unfortunately I'm not familiar with how the Fiber framework works. One thing I'm noticing in your last snippet however is that you're mixing the v1 version of the Clerk Go SDK with v2. There should probably only be one version active. I'd suggest sticking with v2. Regarding the middleware, hopefully our own middleware might provide some guidelines on what needs to be done. clerk-sdk-go/http/middleware.go Line 38 in 195ed86
The idea is that you need to get the Bearer token from the Authorization header and call Without knowing how Fiber works, I wonder if there's a way that you can adapt a "plain middleware" like Hope the above helps, sorry I cannot offer more assistance as I'm unfamiliar with Fiber. |
Hi @gkats , Thanks for the feedback, i tried by following the v2 guide (https://clerk.com/docs/references/go/verifying-sessions#manually-verify-a-session-token) but i getting this error when verifying the token: I think is this snippet from the doc requires the JWK. To be honest, i am also new to Go and Fiber. I am more familiar to Next.js but want to try something new. claims, err := jwt.Verify(r.Context(), &jwt.VerifyParams{
Token: sessionToken,
}) I tried to inject the Clerk middleware with Fiber adaptor to convert the handler, but it keep throwing error during |
Hello @imchivaa, which version of the Clerk Go SDK are you using? Could you try again with v2.0.2-beta.7 which is the latest version? I'm running the following code in my "protected" handler (copied from the Clerk docs) and it works fine. sessionToken := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
claims, err := jwt.Verify(r.Context(), &jwt.VerifyParams{
Token: sessionToken,
}) Sorry about the inconvenience with the beta versions, I expect v2 to go GA this week. I realize the beta versioning scheme might be causing some confusion at the moment. |
Hi @gkats , Thanks for the follow up. I confirm it works with beta 7. I was using version v2.0.0. Point it to beta 7 and i able to follow the sample code from Clerk docs. Thank you again for spending your time on this. 👍 |
But i notice one thing @gkats , with the beta 7, i frequently hit this when generating token using Clerk-Expo package: I didn't get this problems when using v2.0.0. Did you get this when running in your project? |
@imchivaa Glad it worked!
Could you please provide more info into what's happening here? I suspect that there's a clock skew issue between your server and your client, but cannot know for sure. You can pass a clock to the verification parameters, but I cannot know how it can sync with your client. |
Thanks for the suggestion @gkats , i will test this our later. I will open a new issue if i found something. Meanwhile, i think we can close this issue since the issue i am facing is resolved now by using the v2.0.2-beta.7. Thank you for your support and feedback. 👍🏾 |
I gonna leave this here just in case someone face this issue in the future, a little late on the follow up, Resolve the issue by sync the date and time on Windows that running go with fiber. adrianhajdin/threads#86 (comment)
|
Doesn't clerk affect performance? |
I think you could use fiber adaptor middleware and the clerk WithHeaderAuthorization() |
@imchivaa can you please post sample code here please? I too am facing a similar issue please. |
@gj1118 , here you go this is my package main
import (
"os"
"mindful/middlewares"
"mindful/routes"
"github.com/clerk/clerk-sdk-go/v2"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/healthcheck"
"github.com/gofiber/fiber/v2/middleware/logger"
)
// Main entry point
func main() {
// Initialize Fiber
app := fiber.New()
// Apply Clerk secret key
clerk.SetKey(os.Getenv("CLERK_SECRET_KEY"))
// Apply some middlewares
app.Use(
middlewares.AuthorizationMiddlewareV1()
)
// Start the application
app.Listen(os.Getenv("HOST"))
} below is my package middlewares
import (
"log"
"net/http"
"os"
"strings"
"mindful/responses"
"github.com/clerk/clerk-sdk-go/v2/jwt"
"github.com/gofiber/fiber/v2"
)
// Middleware that will intercept the Authorization header and validate the JWT
func AuthorizationMiddlewareV1() fiber.Handler {
unauthorizedMsg := "unauthorized"
return func(c *fiber.Ctx) error {
if os.Getenv("APP_ENV") == "development" {
log.Println("Skip token validation on local env")
c.Request().Header.Set("userId", "user_2f2YcXoXqC2gFRKPt8mnuD8AHan")
return c.Next()
}
headerAuth := c.Request().Header.Peek("Authorization")
if headerAuth == nil {
log.Println("Missing authorization header")
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: unauthorizedMsg})
}
sessionTokenBearer := string(headerAuth[:])
if sessionTokenBearer == "" {
log.Println("Missing Bearer token")
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: unauthorizedMsg})
}
sessionToken := strings.TrimPrefix(sessionTokenBearer, "Bearer ")
if sessionToken == "" {
log.Println("Missing token after Bearer")
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: unauthorizedMsg})
}
claims, err := jwt.Verify(c.Context(), &jwt.VerifyParams{
Token: sessionToken,
})
if err != nil {
log.Println("Clerk auth verify token error: ", err)
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: unauthorizedMsg})
}
if claims == nil {
log.Println("Clerk auth session claim error: ", err)
return c.Status(http.StatusUnauthorized).JSON(responses.AuthResponse{Status: http.StatusUnauthorized, Message: unauthorizedMsg})
}
log.Println(claims.ActiveOrganizationRole)
c.Request().Header.Set("userId", claims.Subject)
return c.Next()
}
} |
Thanks @imchivaa . So you are not using clerk for validating the tokens in your middlware? If so how did you handle the refresh tokens ? |
Hello,
I am using Fiber with Clerk and i like to validate the token sending by the frontend. The documentation shows validation using mux, how do i apply this to Fiber?
Anyone implemented this before would share some insights? Thanks.
The text was updated successfully, but these errors were encountered: