honojs-middleware/packages/firebase-auth/src/index.ts

90 lines
2.5 KiB
TypeScript
Raw Normal View History

2022-07-28 13:58:54 +08:00
import { Context, Handler } from "hono";
import {
EmulatorEnv,
Auth,
WorkersKVStoreSingle,
KeyStorer,
FirebaseIdToken,
} from "firebase-auth-cloudflare-workers";
2022-07-23 22:56:20 +08:00
2022-07-28 13:58:54 +08:00
export interface VerifyFirebaseAuthEnv extends EmulatorEnv {
PUBLIC_JWK_CACHE_KEY?: string | undefined;
PUBLIC_JWK_CACHE_KV?: KVNamespace | undefined;
2022-07-23 22:56:20 +08:00
}
2022-07-28 13:58:54 +08:00
export interface VerifyFirebaseAuthConfig {
projectId: string;
authorizationHeaderKey?: string;
keyStore?: KeyStorer;
keyStoreInitializer?: (c: Context) => KeyStorer;
disableErrorLog?: boolean;
2022-07-29 22:03:09 +08:00
firebaseEmulatorHost?: string;
2022-07-28 13:58:54 +08:00
}
const defaultKVStoreJWKCacheKey = "verify-firebase-auth-cached-public-key";
const defaultKeyStoreInitializer = (c: Context): KeyStorer => {
return WorkersKVStoreSingle.getOrInitialize(
c.env.PUBLIC_JWK_CACHE_KEY ?? defaultKVStoreJWKCacheKey,
c.env.PUBLIC_JWK_CACHE_KV
);
};
export const verifyFirebaseAuth = (
userConfig: VerifyFirebaseAuthConfig
2022-07-29 22:19:14 +08:00
): Handler => {
2022-07-28 13:58:54 +08:00
const config = {
projectId: userConfig.projectId,
AuthorizationHeaderKey:
userConfig.authorizationHeaderKey ?? "Authorization",
KeyStore: userConfig.keyStore,
keyStoreInitializer:
userConfig.keyStoreInitializer ?? defaultKeyStoreInitializer,
disableErrorLog: userConfig.disableErrorLog,
2022-07-29 22:03:09 +08:00
firebaseEmulatorHost: userConfig.firebaseEmulatorHost,
2022-07-28 13:58:54 +08:00
};
return async (c, next) => {
const authorization = c.req.headers.get(config.AuthorizationHeaderKey);
if (authorization === null) {
return new Response(null, {
status: 400,
});
}
const jwt = authorization.replace(/Bearer\s+/i, "");
const auth = Auth.getOrInitialize(
config.projectId,
config.KeyStore ?? config.keyStoreInitializer(c)
);
try {
2022-07-29 22:03:09 +08:00
const idToken = await auth.verifyIdToken(jwt, {
FIREBASE_AUTH_EMULATOR_HOST:
config.firebaseEmulatorHost ?? c.env.FIREBASE_AUTH_EMULATOR_HOST,
});
2022-07-28 13:58:54 +08:00
setFirebaseToken(c, idToken);
} catch (err) {
if (!userConfig.disableErrorLog) {
console.error({
message: "failed to verify the requested firebase token",
err,
});
}
return new Response(null, {
status: 401,
});
}
await next();
};
};
const idTokenContextKey = "firebase-auth-cloudflare-id-token-key";
const setFirebaseToken = (c: Context, idToken: FirebaseIdToken) =>
c.set(idTokenContextKey, idToken);
export const getFirebaseToken = (c: Context): FirebaseIdToken | null => {
const idToken = c.get(idTokenContextKey);
if (!idToken) return null;
return idToken;
};