Skip to content

Commit 036e954

Browse files
feat(jwk): Add headerName to jwk middleware
1 parent 530ab09 commit 036e954

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

src/middleware/jwk/index.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,57 @@ describe('JWK', () => {
434434
})
435435
})
436436

437+
describe('Credentials in custom header', () => {
438+
let handlerExecuted: boolean
439+
440+
beforeEach(() => {
441+
handlerExecuted = false
442+
})
443+
444+
const app = new Hono()
445+
446+
app.use('/auth-with-keys/*', jwk({ keys: verify_keys, headerName: 'x-custom-auth-header' }))
447+
448+
app.get('/auth-with-keys/*', (c) => {
449+
handlerExecuted = true
450+
const payload = c.get('jwtPayload')
451+
return c.json(payload)
452+
})
453+
454+
it('Should not authorize', async () => {
455+
const req = new Request('http://localhost/auth-with-keys/a')
456+
const res = await app.request(req)
457+
expect(res).not.toBeNull()
458+
expect(res.status).toBe(401)
459+
expect(await res.text()).toBe('Unauthorized')
460+
expect(handlerExecuted).toBeFalsy()
461+
})
462+
463+
it('Should not authorize even if default authorization header present', async () => {
464+
const credential = await Jwt.sign({ message: 'hello world' }, test_keys.private_keys[0])
465+
466+
const req = new Request('http://localhost/auth-with-keys/a')
467+
req.headers.set('Authorization', `Bearer ${credential}`)
468+
const res = await app.request(req)
469+
expect(res).not.toBeNull()
470+
expect(res.status).toBe(401)
471+
expect(await res.text()).toBe('Unauthorized')
472+
expect(handlerExecuted).toBeFalsy()
473+
})
474+
475+
it('Should authorize', async () => {
476+
const credential = await Jwt.sign({ message: 'hello world' }, test_keys.private_keys[1])
477+
478+
const req = new Request('http://localhost/auth-with-keys/a')
479+
req.headers.set('x-custom-auth-header', `Bearer ${credential}`)
480+
const res = await app.request(req)
481+
expect(res).not.toBeNull()
482+
expect(res.status).toBe(200)
483+
expect(await res.json()).toEqual({ message: 'hello world' })
484+
expect(handlerExecuted).toBeTruthy()
485+
})
486+
})
487+
437488
describe('Credentials in cookie', () => {
438489
let handlerExecuted: boolean
439490

src/middleware/jwk/jwk.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,18 @@ import type { HonoJsonWebKey } from '../../utils/jwt/jws'
2222
* @param {string | ((ctx: Context) => Promise<string> | string)} [options.jwks_uri] - If set to a URI string or a function that returns a URI string, attempt to fetch JWKs from it. The response must be a JSON object containing a `keys` array, which will be merged with the `keys` option.
2323
* @param {boolean} [options.allow_anon] - If set to `true`, the middleware allows requests without a token to proceed without authentication.
2424
* @param {string} [options.cookie] - If set, the middleware attempts to retrieve the token from a cookie with these options (optionally signed) only if no token is found in the header.
25+
* @param {string} [options.headerName='Authorization'] - The name of the header to look for the JWT token. Default is 'Authorization'.
2526
* @param {RequestInit} [init] - Optional init options for the `fetch` request when retrieving JWKS from a URI.
2627
* @returns {MiddlewareHandler} The middleware handler function.
2728
*
2829
* @example
2930
* ```ts
3031
* const app = new Hono()
3132
*
32-
* app.use("/auth/*", jwk({ jwks_uri: (c) => `https://${c.env.authServer}/.well-known/jwks.json` }))
33+
* app.use("/auth/*", jwk({
34+
* jwks_uri: (c) => `https://${c.env.authServer}/.well-known/jwks.json`,
35+
* headerName: 'x-custom-auth-header', // Optional, default is 'Authorization'
36+
* }))
3337
*
3438
* app.get('/auth/page', (c) => {
3539
* return c.text('You are authorized')
@@ -45,6 +49,7 @@ export const jwk = (
4549
cookie?:
4650
| string
4751
| { key: string; secret?: string | BufferSource; prefixOptions?: CookiePrefixOptions }
52+
headerName?: string
4853
},
4954
init?: RequestInit
5055
): MiddlewareHandler => {
@@ -57,7 +62,9 @@ export const jwk = (
5762
}
5863

5964
return async function jwk(ctx, next) {
60-
const credentials = ctx.req.raw.headers.get('Authorization')
65+
const headerName = options.headerName || 'Authorization'
66+
67+
const credentials = ctx.req.raw.headers.get(headerName)
6168
let token
6269
if (credentials) {
6370
const parts = credentials.split(/\s+/)

0 commit comments

Comments
 (0)