From 69c3983d2073cbcaa45ecf8eb635bcd16dd36218 Mon Sep 17 00:00:00 2001 From: Joaquin Gimenez Date: Tue, 4 Mar 2025 18:20:59 -0600 Subject: [PATCH] feat(cloudflare-access): Add support to read JWT from Cookie (#1001) --- .changeset/sixty-geese-knock.md | 5 +++++ packages/cloudflare-access/src/index.test.ts | 18 +++++++++++++++++- packages/cloudflare-access/src/index.ts | 7 ++++--- 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 .changeset/sixty-geese-knock.md diff --git a/.changeset/sixty-geese-knock.md b/.changeset/sixty-geese-knock.md new file mode 100644 index 00000000..3d94b73a --- /dev/null +++ b/.changeset/sixty-geese-knock.md @@ -0,0 +1,5 @@ +--- +'@hono/cloudflare-access': minor +--- + +Add support to read JWT from Cookie diff --git a/packages/cloudflare-access/src/index.test.ts b/packages/cloudflare-access/src/index.test.ts index ba5ff420..80264d3c 100644 --- a/packages/cloudflare-access/src/index.test.ts +++ b/packages/cloudflare-access/src/index.test.ts @@ -229,6 +229,22 @@ describe('Cloudflare Access middleware', async () => { expect(await res.text()).toBe('foo') }) + it('Should work when sending jwt as a Cookie', async () => { + const token = generateJWT(keyPair1.privateKey, { + sub: '1234567890', + iss: 'https://my-cool-team-name.cloudflareaccess.com', + }) + + const res = await app.request('http://localhost/hello-behind-access', { + headers: { + Cookie: `CF_Authorization=${token}`, + }, + }) + expect(res).not.toBeNull() + expect(res.status).toBe(200) + expect(await res.text()).toBe('foo') + }) + it('Should work with tokens signed by the 2ยบ key in the public keys list', async () => { const token = generateJWT(keyPair2.privateKey, { sub: '1234567890', @@ -279,7 +295,7 @@ describe('Cloudflare Access middleware', async () => { expect(res).not.toBeNull() expect(res.status).toBe(500) expect(await res.json()).toEqual({ - err: 'Error: Authentication error: The Access Organization \'my-cool-team-name\' does not exist', + err: "Error: Authentication error: The Access Organization 'my-cool-team-name' does not exist", }) }) diff --git a/packages/cloudflare-access/src/index.ts b/packages/cloudflare-access/src/index.ts index 67cc578b..1a624128 100644 --- a/packages/cloudflare-access/src/index.ts +++ b/packages/cloudflare-access/src/index.ts @@ -1,4 +1,5 @@ import type { Context } from 'hono' +import { getCookie } from 'hono/cookie'; import { createMiddleware } from 'hono/factory' import { HTTPException } from 'hono/http-exception' @@ -133,11 +134,11 @@ async function getPublicKeys(accessTeamName: string) { } function getJwt(c: Context) { - const authHeader = c.req.header('cf-access-jwt-assertion') - if (!authHeader) { + const jwt = c.req.header('cf-access-jwt-assertion') ?? getCookie(c, 'CF_Authorization') + if (!jwt) { return null } - return authHeader.trim() + return jwt.trim() } function decodeJwt(token: string): DecodedToken {