0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-21 18:18:57 +01:00

feat(jwt): Support custom secret keys for signing JWTs (#3546)

* Support custom secret keys for signing JWTs

- Expanded key type check to include 'secret' for JWT signing. This aligns importPrivateKey method with importPublicKey method for handling "secret" type keys.

- Added a test case to sign, verify, and decode using a custom secret, ensuring the correct flow and error handling with mismatched keys.

* update comment for rejected private key imports
This commit is contained in:
Kaan Ozdokmeci 2024-10-23 10:59:09 +02:00 committed by GitHub
parent 7735f2f03c
commit 0a99bd3e74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 2 deletions

View File

@ -50,8 +50,10 @@ async function importPrivateKey(key: SignatureKey, alg: KeyImporterAlgorithm): P
throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.')
}
if (isCryptoKey(key)) {
if (key.type !== 'private') {
throw new Error(`unexpected non private key: CryptoKey.type is ${key.type}`)
if (key.type !== 'private' && key.type !== 'secret') {
throw new Error(
`unexpected key type: CryptoKey.type is ${key.type}, expected private or secret`
)
}
return key
}

View File

@ -235,6 +235,48 @@ describe('JWT', () => {
expect(err instanceof JwtTokenSignatureMismatched).toBe(true)
})
it('sign & verify & decode with a custom secret', async () => {
const payload = { message: 'hello world' }
const algorithm = {
name: 'HMAC',
hash: {
name: 'SHA-256',
},
}
const secret = await crypto.subtle.importKey(
'raw',
Buffer.from('cefb73234d5fae4bf27662900732b52943e8d53e871fe0f353da95de4599c21d', 'hex'),
algorithm,
false,
['sign', 'verify']
)
const tok = await JWT.sign(payload, secret)
const expected =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXNzYWdlIjoiaGVsbG8gd29ybGQifQ.qunGhchNXH_unqWXN6hB0Elhzr5SykSXVhklLti1aFI'
expect(tok).toEqual(expected)
const verifiedPayload = await JWT.verify(tok, secret)
expect(verifiedPayload).not.toBeUndefined()
expect(verifiedPayload).toEqual(payload)
const invalidSecret = await crypto.subtle.importKey(
'raw',
Buffer.from('cefb73234d5fae4bf27662900732b52943e8d53e871fe0f353da95de41111111', 'hex'),
algorithm,
false,
['sign', 'verify']
)
let err = null
let authorized
try {
authorized = await JWT.verify(tok, invalidSecret)
} catch (e) {
err = e
}
expect(authorized).toBeUndefined()
expect(err instanceof JwtTokenSignatureMismatched).toBe(true)
})
const rsTestCases = [
{
alg: AlgorithmTypes.RS256,