本文へ移動

JWK Auth ミドルウェア ​

JWK Auth ミドルウェアは、JWK(JSON Web Key)でトークンを検証してリクエストを認証します。Authorization ヘッダーと、指定されていれば Cookie などの他のソースを確認します。指定した keys でトークンを検証し、jwks_uri があればそこから鍵を取得します。cookie オプションを設定すると、Cookie からのトークン抽出もサポートします。

このミドルウェアの検証内容 ​

各トークンに対して、jwk() は次の処理を行います。

  • JWT ヘッダーの形式を解析、検証します。
  • kid ヘッダーを必須とし、kid で一致する鍵を探します。
  • 対称アルゴリズム(HS256、HS384、HS512)を拒否します。
  • ヘッダーの alg が、設定した alg 許可リストに含まれることを要求します。
  • 一致した JWK に alg フィールドがあれば、JWT ヘッダーの alg と一致することを要求します。
  • 一致した鍵でトークンの署名を検証します。
  • デフォルトで、時刻に関するクレーム nbf、exp、iat を検証します。

任意のクレーム検証は、verification オプションで設定できます。

  • iss:指定した場合、発行者を検証します。
  • aud:指定した場合、対象者を検証します。

上記以外の追加のトークン確認(アプリケーション独自の認可ルールなど)が必要なら、jwk() の後に独自のミドルウェアを追加してください。

情報

クライアントが送信する Authorization ヘッダーには、指定された認証スキームが必要です。

例:Bearer my.token.value または Basic my.token.value

インポート ​

ts
import { Hono } from 'hono'
import { jwk } from 'hono/jwk'
import { verifyWithJwks } from 'hono/jwt'

使い方 ​

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')
})

ペイロードを取得します。

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 }
})

匿名アクセス:

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' })
})

ミドルウェアの外での verifyWithJwks の使用 ​

verifyWithJwks ユーティリティ関数は、SvelteKit の SSR ページなど、Hono のミドルウェアコンテキスト以外のサーバー環境でも JWT トークンを検証できます。

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 },
  }
)

JWKS 取得リクエストのオプション設定 ​

jwks_uri からの JWKS 取得方法を設定するには、fetch リクエストのオプションを jwk() の第 2 引数に渡します。

この引数は RequestInit で、JWKS の取得リクエストにのみ使用されます。

ts
const app = new Hono()

app.use(
  '/auth/*',
  jwk(
    {
      jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
      alg: ['RS256'],
    },
    {
      headers: {
        Authorization: 'Bearer TOKEN',
      },
    }
  )
)

オプション ​

required alg: AsymmetricAlgorithm[] ​

トークン検証で許可する非対称アルゴリズムの配列。

利用可能な型は RS256 | RS384 | RS512 | PS256 | PS384 | PS512 | ES256 | ES384 | ES512 | EdDSA です。

optional keys: HonoJsonWebKey[] | (c: Context) => Promise<HonoJsonWebKey[]> ​

公開鍵の値、またはそれらを返す関数。関数は Context オブジェクトを受け取ります。

optional jwks_uri: string | (c: Context) => Promise<string> ​

設定すると、この URI から JWK の取得を試みます。keys を含む JSON レスポンスを想定し、取得した鍵を指定済みの keys オプションに追加します。Context を使って JWKS URI を動的に決めるコールバック関数も渡せます。

optional allow_anon: boolean ​

true にすると、有効なトークンを持たないリクエストも通過を許可します。c.get('jwtPayload') で認証済みか確認してください。デフォルトは false です。

設定すると、この値をキーとして cookie ヘッダーから値を取得し、トークンとして検証します。

optional headerName: string ​

JWT トークンを探すヘッダー名。デフォルトは Authorization です。

optional realm: string ​

401 レスポンスで返す WWW-Authenticate チャレンジヘッダーの realm パラメーターで示す保護領域です。デフォルトはリクエスト URL です。

optional verification: VerifyOptions ​

署名検証に加えて、クレームの検証動作を設定します。

optional VerifyOptions.iss: string | RegExp ​

トークンの検証で期待する発行者です。未設定なら iss クレームは検証されません。

optional VerifyOptions.aud: string | string[] | RegExp ​

トークンの検証で期待する対象者です。設定した場合、トークンには aud クレームが必要で、少なくとも 1 つの対象者の値が一致しなければなりません。

optional VerifyOptions.nbf: boolean ​

nbf(有効開始時刻)クレームが存在し、この値が true なら検証します。デフォルトは true です。

optional VerifyOptions.iat: boolean ​

iat(発行時刻)クレームが存在し、この値が true なら検証します。デフォルトは true です。

optional VerifyOptions.exp: boolean ​

exp(有効期限)クレームが存在し、この値が true なら検証します。デフォルトは true です。

MIT ライセンスで公開されています。