Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 38 additions & 19 deletions docs/middleware/keyauth.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,38 +221,56 @@
#> Successfully authenticated!
```


Check failure on line 224 in docs/middleware/keyauth.md

View workflow job for this annotation

GitHub Actions / markdownlint

Multiple consecutive blank lines

docs/middleware/keyauth.md:224 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md012.md

Check failure on line 225 in docs/middleware/keyauth.md

View workflow job for this annotation

GitHub Actions / markdownlint

Multiple consecutive blank lines

docs/middleware/keyauth.md:225 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 3] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md012.md
## Key Extractors

The middleware extracts the API key from the request using an `Extractor`. You can specify one or more extractors in the configuration.
KeyAuth uses an `Extractor` from the shared [extractors](../guide/extractors) package to retrieve the API key from the request. You can specify one or more extractors in the configuration. For a full list of extractors, chaining, and advanced usage, see the [Extractors Guide](../guide/extractors).

### Built-in Extractors
### Typical Usage

The following extractors are available:
Specify the extractor in the config. For example, to extract from a cookie:

- `keyauth.FromHeader(header string)`: Extracts the key from the specified header.
- `keyauth.FromAuthHeader(header, authScheme string)`: Extracts the key from an authorization header (e.g., `Authorization: Bearer <key>`).
- `keyauth.FromQuery(param string)`: Extracts the key from a URL query parameter.
- `keyauth.FromParam(param string)`: Extracts the key from a URL path parameter.
- `keyauth.FromCookie(name string)`: Extracts the key from a cookie.
- `keyauth.FromForm(name string)`: Extracts the key from a form field.
```go
app.Use(keyauth.New(keyauth.Config{
Extractor: extractors.FromCookie("access_token"),
Validator: validateAPIKey,
}))
```

### Chaining Extractors
To use the default (Authorization header with Bearer scheme):

You can use `keyauth.Chain` to try multiple extractors until one succeeds. The first successful extraction is used.
```go
app.Use(keyauth.New(keyauth.Config{
Validator: validateAPIKey, // Extractor defaults to FromAuthHeader("Bearer")
}))
```

To try multiple sources (header, then query):

```go
// This will try to extract the key from:
// 1. The "X-API-Key" header
// 2. The "api_key" query parameter
app.Use(keyauth.New(keyauth.Config{
Extractor: keyauth.Chain(
keyauth.FromHeader("X-API-Key"),
keyauth.FromQuery("api_key"),
Extractor: extractors.Chain(
extractors.FromHeader("X-API-Key"),
extractors.FromQuery("api_key"),
),
Validator: validateAPIKey,
}))
```

For custom logic, use `extractors.FromCustom`:

```go
app.Use(keyauth.New(keyauth.Config{
Extractor: extractors.FromCustom(func(c fiber.Ctx) (string, error) {
return c.Get("X-My-API-Key"), nil
}),
Validator: validateAPIKey,
}))
```

Refer to the [Extractors Guide](../guide/extractors) for details, security notes, and advanced configuration.

## Config

| Property | Type | Description | Default |
Expand All @@ -261,14 +279,15 @@
| SuccessHandler | `fiber.Handler` | SuccessHandler defines a function which is executed for a valid key. | `c.Next()` |
| ErrorHandler | `fiber.ErrorHandler` | ErrorHandler defines a function which is executed for an invalid key. By default a 401 response with a `WWW-Authenticate` challenge is sent. | Default error handler |
| Validator | `func(fiber.Ctx, string) (bool, error)` | **Required.** Validator is a function to validate the key. | `nil` (panic) |
| Extractor | `keyauth.Extractor` | Extractor defines how to retrieve the key from the request. Use helper functions like `keyauth.FromAuthHeader` or `keyauth.FromCookie`. | `keyauth.FromAuthHeader("Authorization", "Bearer")` |
| Extractor | `extractors.Extractor` | Extractor defines how to retrieve the key from the request. Use helper functions from the shared extractors package, e.g. `extractors.FromAuthHeader("Bearer")` or `extractors.FromCookie("access_token")`. | `extractors.FromAuthHeader("Bearer")` |
| Realm | `string` | Realm specifies the protected area name used in the `WWW-Authenticate` header. | `"Restricted"` |
| Challenge | `string` | Value of the `WWW-Authenticate` header when no `Authorization` scheme is present. | `ApiKey realm="Restricted"` |
| Error | `string` | Error code appended as the `error` parameter in Bearer challenges. Must be `invalid_request`, `invalid_token`, or `insufficient_scope`. | `""` |
| ErrorDescription| `string` | Human-readable text for the `error_description` parameter in Bearer challenges. Requires `Error`. | `""` |
| ErrorURI | `string` | URI identifying a human-readable web page with information about the `error` in Bearer challenges. Requires `Error` and must be an absolute URI. | `""` |
| Scope | `string` | Space-delimited list of scopes for the `scope` parameter in Bearer challenges. Each token must conform to the RFC 6750 `scope-token` syntax and requires `Error` set to `insufficient_scope`. | `""` |


Check failure on line 290 in docs/middleware/keyauth.md

View workflow job for this annotation

GitHub Actions / markdownlint

Multiple consecutive blank lines

docs/middleware/keyauth.md:290 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md012.md
## Default Config

```go
Expand All @@ -280,6 +299,6 @@
return c.Status(fiber.StatusUnauthorized).SendString(ErrMissingOrMalformedAPIKey.Error())
},
Realm: "Restricted",
Extractor: FromAuthHeader(fiber.HeaderAuthorization, "Bearer"),
Extractor: extractors.FromAuthHeader("Bearer"),
}
```
7 changes: 4 additions & 3 deletions middleware/keyauth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/extractors"
)

const (
Expand Down Expand Up @@ -81,8 +82,8 @@ type Config struct {

// Extractor is a function to extract the key from the request.
//
// Optional. Default: FromAuthHeader("Authorization", "Bearer")
Extractor Extractor
// Optional. Default: extractors.FromAuthHeader("Bearer")
Extractor extractors.Extractor
}

// ConfigDefault is the default config
Expand All @@ -94,7 +95,7 @@ var ConfigDefault = Config{
return c.Status(fiber.StatusUnauthorized).SendString(ErrMissingOrMalformedAPIKey.Error())
},
Realm: "Restricted",
Extractor: FromAuthHeader(fiber.HeaderAuthorization, "Bearer"),
Extractor: extractors.FromAuthHeader("Bearer"),
}

// configDefault is a helper function to set default values
Expand Down
3 changes: 2 additions & 1 deletion middleware/keyauth/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/extractors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -49,7 +50,7 @@ func Test_KeyAuth_ConfigDefault_CustomConfig(t *testing.T) {
successHandler := func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusOK) }
errorHandler := func(c fiber.Ctx, _ error) error { return c.SendStatus(fiber.StatusForbidden) }
validator := func(_ fiber.Ctx, _ string) (bool, error) { return true, nil }
extractor := FromHeader("X-API-Key")
extractor := extractors.FromHeader("X-API-Key")

cfg := configDefault(Config{
Next: nextFunc,
Expand Down
Loading
Loading