Cloudflare Workers + Hono で jwt を扱うときにハマった (original) (raw)

最初

jsonwebtoken (https://www.npmjs.com/package/jsonwebtoken) で ES256 を使って生成/検証しようとしたけどエラーでうまくいかなかった。

調査

https://github.com/auth0/node-jsonwebtoken/blob/v9.0.2/sign.js#L117

createPrivateKey がエラーを発生させているので、createSecretKey が使われている模様、なので type == 'secret' になってしまってエラー (https://github.com/auth0/node-jsonwebtoken/blob/v9.0.2/sign.js#L130) が出ている。

node_modules/jsonwebtoken/sign.js をいじってエラーを出力すると createPrivateKey が定義されていないようだった。

node_compat_v2 は設定していたが、リストを見ると createPrivateKey は対応していない模様。

https://developers.cloudflare.com/workers/runtime-apis/nodejs/crypto/#keys

解決

https://hono.dev/docs/helpers/jwt#jwt-authentication-helper

どうしたものかと調べていたら hono のドキュメントに行き当たり、ヘルパー関数があるとのことなのでそれを使うことにしたらうまく行った。

メモ

ES256 の鍵の作り方

https://blog.authlib.org/2023/openssl-ec-keys

openssl ecparam -name prime256v1 -genkey -noout -out test.key openssl ec -in test.key -pubout -out test.pem

base64 エンコードして環境変数にいれた (とりあえず .dev.vars に書いた)

cat test.key | base64 | pbcopy cat test.pem | base64 | pbcopy

コード

import { sign, verify } from "hono/jwt"; ... const token = await sign( { ...payload, exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 }, Buffer.from(c.env.PRIVATE_KEY, "base64").toString("ascii"), "ES256", ); console.log( await verify( token, Buffer.from(c.env.PUBLIC_KEY, "base64").toString("ascii"), "ES256", ), ); ...

感想