Skip to content
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

Add support for fasthttp or decouple FinishRegistration from net/http #297

Open
william-mens opened this issue Sep 19, 2024 · 2 comments
Open
Labels
status/needs-triage Issues that need to be triaged. type/feature-request Feature Requests

Comments

@william-mens
Copy link

Description

This is a feature request to improve the flexibility of the WebAuthn library by decoupling the FinishRegistration method (and similar methods) from being tied to net/http. Currently, frameworks like Fiber, which are based on fasthttp, encounter compatibility issues because the library only supports *http.Request.

When using Fiber’s c.Request() (which returns a *fasthttp.Request), developers encounter a type mismatch error, forcing them to rely on adaptors (such as fasthttpadaptor) to convert between fasthttp.Request and *http.Request. While this workaround works, it adds unnecessary complexity and dependency bloat to the application.

Frameworks like Fiber are popular for their performance and low resource usage.
Adding native support for fasthttp or abstracting the HTTP request layer will remove the need for adaptors and keep applications lightweight. A more flexible API will broaden the potential use of the library across a wider range of Go web frameworks.

Proposed Solution:

  • Consider decoupling the WebAuthn methods like FinishRegistration from being tightly bound to *http.Request.
  • Implement an abstraction layer using interfaces that can support both net/http and fasthttp.
  • Allow developers to pass custom request-handling logic, making the library more flexible across different frameworks.

Steps to Reproduce:

  • Use the WebAuthn library in a Fiber-based application.
  • Attempt to call FinishRegistration using c.Request() (Fiber's fasthttp.Request).
  • Observe the type mismatch error: cannot use c.Request() (value of type *fasthttp.Request) as *http.Request.

Current Workaround:
To bypass the type incompatibility, developers must use an adaptor:
req, err := fasthttpadaptor.ConvertRequest(c.Context())
if err != nil {
// Handle error
}
credential, err := webAuthn.FinishRegistration(authAuth, user, sessionData, req)

Use Case

No response

Documentation

No response

@william-mens william-mens added status/needs-triage Issues that need to be triaged. type/feature-request Feature Requests labels Sep 19, 2024
@james-d-elliott
Copy link
Member

james-d-elliott commented Sep 19, 2024

It's already supported. Take a look at the implementation specifics of these functions, you'll realize they're just decorators for lower lower level functions which can parse bytes and io.Readers.

Example:

	if response, err := protocol.ParseCredentialCreationResponseBody(bytes.NewReader(ctx.PostBody())); err != nil {
		panic(err)
	} else if credential, err := webauthn.CreateCredential(user, sessionData, response); err != nil {
	        panic(err)
	} else {
                ...
	}

@william-mens
Copy link
Author

Hello James,
Thank you for your prompt response! I really appreciate the clarification. I have implemented the suggested changes, and everything is working smoothly now—no more errors!

I also think it would be beneficial to update the documentation with these examples. If you're open to it, I would be happy to assist with that.

Lastly, I'm encountering a minor challenge when I log the error from the credential creation process. I'm receiving the message: "Error validating origin." Below is the relevant test code for my WebAuthn configuration:

app := fiber.New()

app.Use(cors.New(cors.Config{
    AllowOrigins: "http://localhost:80",
    AllowHeaders: "Origin, Content-Type, Accept",
}))

wconfig := &webauthn.Config{
    RPDisplayName: "Go Webauthn",
    RPID:          "localhost",
    RPOrigins:     []string{"http://localhost:80"},
}
func completeRegistration(c *fiber.Ctx) error {
    // Retrieve the user
    userID := "11111111" // sample userId
    user, exists := users[userID]
    if !exists {
        return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
    }

  
    var requestBody bytes.Buffer
    if _, err := requestBody.ReadFrom(c.Body()); err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Unable to read request body"})
    }

    response, err := protocol.ParseCredentialCreationResponseBody(&requestBody)
    if err != nil {
        return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
    }

    credential, err := webAuthn.CreateCredential(user, *user.Session, response)
    if err != nil {
        fmt.Println("Error during credential creation:", err) //
<img width="1081" alt="Screenshot 2024-09-20 at 1 37 56 PM" src="https://github.com/user-attachments/assets/eca47e27-05b1-473c-8357-f8ae36aa1e08">
Error validating origin.
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Error during credential creation"})
    }

    user.Credentials = append(user.Credentials, *credential)

    return c.JSON(fiber.Map{
        "status":     "registration completed",
        "credential": credential,
    })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/needs-triage Issues that need to be triaged. type/feature-request Feature Requests
Projects
None yet
Development

No branches or pull requests

2 participants