# JWK Auth Middleware
The JWK Auth Middleware authenticates requests by verifying tokens using JWK (JSON Web Key). It checks for an `Authorization` header and other configured sources, such as cookies, if specified. It validates tokens using the provided `keys`, retrieves keys from `jwks_uri` if specified, and supports token extraction from cookies if the `cookie` option is set.
## What this middleware validates
For each token, `jwk()`:
- Parses and validates the JWT header format.
- Requires a `kid` header and finds a matching key by `kid`.
- Rejects symmetric algorithms (`HS256`, `HS384`, `HS512`).
- Requires the header `alg` to be included in the configured `alg` allowlist.
- If a matched JWK has an `alg` field, requires it to match the JWT header `alg`.
- Verifies the token signature with the matched key.
- By default, validates time-based claims: `nbf`, `exp`, and `iat`.
Optional claim validation can be configured with the `verification` option:
- `iss`: validates issuer when provided.
- `aud`: validates audience when provided.
If you need additional token checks beyond the above (for example, custom application-level authorization rules), add them in your own middleware after `jwk()`.
:::info
The Authorization header sent from the client must have a specified scheme.
Example: `Bearer my.token.value` or `Basic my.token.value`
:::
## Import
```ts
import { Hono } from 'hono'
import { jwk } from 'hono/jwk'
import { verifyWithJwks } from 'hono/jwt'
```
## Usage
```ts
const app = new Hono()
app.use(
'/auth/*',
jwk({
jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
alg: ['RS256'],
})
)
app.get('/auth/page', (c) => {
return c.text('You are authorized')
})
```
Get payload:
```ts
const app = new Hono()
app.use(
'/auth/*',
jwk({
jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
alg: ['RS256'],
})
)
app.get('/auth/page', (c) => {
const payload = c.get('jwtPayload')
return c.json(payload) // eg: { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
})
```
Anonymous access:
```ts
const app = new Hono()
app.use(
'/auth/*',
jwk({
jwks_uri: (c) =>
`https://${c.env.authServer}/.well-known/jwks.json`,
alg: ['RS256'],
allow_anon: true,
})
)
app.get('/auth/page', (c) => {
const payload = c.get('jwtPayload')
return c.json(payload ?? { message: 'hello anon' })
})
```
## Using `verifyWithJwks` outside of middleware
The `verifyWithJwks` utility function can be used to verify JWT tokens outside of Hono's middleware context, such as in SvelteKit SSR pages or other server-side environments:
```ts
const id_payload = await verifyWithJwks(
id_token,
{
jwks_uri: 'https://your-auth-server/.well-known/jwks.json',
allowedAlgorithms: ['RS256'],
},
{
cf: { cacheEverything: true, cacheTtl: 3600 },
}
)
```
## Configuring JWKS fetch request options
To configure how JWKS is retrieved from `jwks_uri`, pass fetch request options as the second argument of `jwk()`.
This argument is `RequestInit` and is used only for the JWKS fetch request.
```ts
const app = new Hono()
app.use(
'/auth/*',
jwk(
{
jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
alg: ['RS256'],
},
{
headers: {
Authorization: 'Bearer TOKEN',
},
}
)
)
```
## Options
### alg: `AsymmetricAlgorithm[]`
An array of allowed asymmetric algorithms used for token verification.
Available types are `RS256` | `RS384` | `RS512` | `PS256` | `PS384` | `PS512` | `ES256` | `ES384` | `ES512` | `EdDSA`.
### keys: `HonoJsonWebKey[] | (c: Context) => Promise`
The values of your public keys, or a function that returns them. The function receives the Context object.
### jwks_uri: `string` | `(c: Context) => Promise`
If this value is set, attempt to fetch JWKs from this URI, expecting a JSON response with `keys`, which are added to the provided `keys` option. You can also pass a callback function to dynamically determine the JWKS URI using the Context.
### allow_anon: `boolean`
If this value is set to `true`, requests without a valid token will be allowed to pass through the middleware. Use `c.get('jwtPayload')` to check if the request is authenticated. The default is `false`.
### cookie: `string`
If this value is set, then the value is retrieved from the cookie header using that value as a key, which is then validated as a token.
### headerName: `string`
The name of the header to look for the JWT token. The default is `Authorization`.
### verification: `VerifyOptions`
Configure claim validation behavior in addition to signature verification:
- `iss`: expected issuer.
- `aud`: expected audience.
- `exp`, `nbf`, `iat`: enabled by default, can be disabled if needed.