> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
> Use this file to discover all available pages before exploring further.

# jwt

> API reference for the JWT Auth middleware

## Import

```typescript theme={null}
import { jwt, sign, verify, decode } from 'hono/jwt'
```

## Usage

```typescript theme={null}
const app = new Hono()

app.use(
  '/auth/*',
  jwt({
    secret: 'it-is-very-secret',
    alg: 'HS256',
  })
)

app.get('/auth/page', (c) => {
  const payload = c.get('jwtPayload')
  return c.text('You are authorized')
})
```

## Options

The `jwt` middleware accepts an options object:

<ParamField path="secret" type="SignatureKey" required>
  A value of your secret key. Required for token verification.
</ParamField>

<ParamField path="alg" type="SignatureAlgorithm" required>
  An algorithm type that is used for verifying. Available types are:

  * `HS256`, `HS384`, `HS512` (HMAC)
  * `RS256`, `RS384`, `RS512` (RSA)
  * `PS256`, `PS384`, `PS512` (RSA-PSS)
  * `ES256`, `ES384`, `ES512` (ECDSA)
  * `EdDSA` (EdDSA)
</ParamField>

<ParamField path="cookie" type="string | { key: string; secret?: string | BufferSource; prefixOptions?: CookiePrefixOptions }">
  If this value is set, then the JWT is retrieved from the cookie using the specified key. Can be:

  * A string: the cookie name
  * An object with `key`, optional `secret` for signed cookies, and optional `prefixOptions`
</ParamField>

<ParamField path="headerName" type="string" default="Authorization">
  The name of the header to look for the JWT token.
</ParamField>

<ParamField path="verification" type="VerifyOptions">
  Additional options for JWT payload verification (e.g., audience, issuer, expiration checks).
</ParamField>

## Signature

```typescript theme={null}
jwt(options: {
  secret: SignatureKey
  cookie?: string | {
    key: string
    secret?: string | BufferSource
    prefixOptions?: CookiePrefixOptions
  }
  alg: SignatureAlgorithm
  headerName?: string
  verification?: VerifyOptions
}): MiddlewareHandler
```

## Context Variable

The middleware sets the decoded JWT payload in the context:

```typescript theme={null}
app.get('/auth/page', (c) => {
  const payload = c.get('jwtPayload')
  console.log(payload) // Decoded JWT payload
  return c.json({ user: payload.sub })
})
```

## Examples

### Basic usage with secret

```typescript theme={null}
app.use(
  '/auth/*',
  jwt({
    secret: 'it-is-very-secret',
    alg: 'HS256',
  })
)
```

### Custom header name

```typescript theme={null}
app.use(
  '/auth/*',
  jwt({
    secret: 'it-is-very-secret',
    alg: 'HS256',
    headerName: 'x-custom-auth-header',
  })
)
```

### JWT from cookie

```typescript theme={null}
app.use(
  '/auth/*',
  jwt({
    secret: 'it-is-very-secret',
    alg: 'HS256',
    cookie: 'jwt_token',
  })
)
```

### Signed cookie

```typescript theme={null}
app.use(
  '/auth/*',
  jwt({
    secret: 'it-is-very-secret',
    alg: 'HS256',
    cookie: {
      key: 'jwt_token',
      secret: 'cookie-secret',
    },
  })
)
```

### With verification options

```typescript theme={null}
app.use(
  '/auth/*',
  jwt({
    secret: 'it-is-very-secret',
    alg: 'HS256',
    verification: {
      audience: 'myapp',
      issuer: 'https://myapp.com',
    },
  })
)
```

### Using RSA keys

```typescript theme={null}
const publicKey = await crypto.subtle.importKey(
  'spki',
  pemToArrayBuffer(publicKeyPem),
  { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },
  false,
  ['verify']
)

app.use(
  '/auth/*',
  jwt({
    secret: publicKey,
    alg: 'RS256',
  })
)
```

## Utility Functions

### sign

Sign a JWT token.

```typescript theme={null}
import { sign } from 'hono/jwt'

const token = await sign(
  { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 60 * 60 },
  'secret',
  'HS256'
)
```

### verify

Verify a JWT token.

```typescript theme={null}
import { verify } from 'hono/jwt'

const payload = await verify(token, 'secret', 'HS256')
```

### decode

Decode a JWT token without verification.

```typescript theme={null}
import { decode } from 'hono/jwt'

const { header, payload } = decode(token)
```

### verifyWithJwks

Verify a JWT token using JWKS.

```typescript theme={null}
import { verifyWithJwks } from 'hono/jwt'

const payload = await verifyWithJwks(token, jwksUrl)
```

## Behavior

* Expects JWT in `Authorization` header with format: `Bearer <token>`
* Returns 401 Unauthorized if:
  * No authorization header or cookie is present
  * Token format is invalid (not exactly 2 parts)
  * Token verification fails
* Sets `WWW-Authenticate` header with error details on failure
* Stores decoded payload in context as `jwtPayload`
* Requires `crypto.subtle.importKey` to be available in runtime
* Supports both header-based and cookie-based token retrieval
