Firebase Auth for Cloudflare Workers
Cloudfire Auth is a JavaScript/TypeScript library designed to integrate Firebase Authentication functionalities directly within Cloudflare Workers environments. Currently at version 0.4.0, it provides core features such as Firebase ID token verification, user retrieval, and user deletion. The library leverages native Cloudflare APIs, specifically Cloudflare KV, for efficient OAuth2 token caching, which is crucial for performance and cost-effectiveness in a serverless context. It is built with a strong emphasis on modern JavaScript, being ESM-only, and offers full TypeScript support, making it suitable for contemporary development workflows. Key differentiators include its tight integration with Cloudflare's ecosystem, minimal external dependencies (only 'jose' for JWT handling), and its focus on solving the specific challenge of running Firebase Auth in a Worker environment where the official Firebase Admin SDK is not directly compatible due to Node.js-specific dependencies.
Common errors
-
Error: Dynamic require of "crypto" is not supported
cause Attempting to use `cloudfire-auth` in a Node.js-incompatible environment (like Cloudflare Workers) while a dependency tries to `require` Node.js built-ins, or if the library itself is incorrectly bundled.fixThis specific library is designed for Cloudflare Workers. Ensure you are importing correctly (`import`) and that your build process for the Worker handles ESM correctly. This error can also indicate a misconfigured dependency attempting to use Node.js crypto, but `cloudfire-auth` aims to avoid this by using `jose` which is universal. -
SyntaxError: Unexpected token 'export'
cause Trying to run ESM-only code in an environment that only supports CommonJS, or a build tool is misconfigured for ESM.fixEnsure your Cloudflare Worker environment and local development setup are configured for ES Modules. If using `npm install` and bundling, verify your bundler (e.g., Webpack, Rollup, esbuild) correctly handles `module` and `exports` fields in `package.json` for ESM. -
Error: Id token is expired. Get a fresh one from your client app and try again.
cause The Firebase ID token provided to `verifyIdToken` has exceeded its validity period (typically 1 hour).fixInstruct the client application to refresh the ID token and send the newly obtained token. Firebase client SDKs automatically handle token refreshing; ensure the client-side logic correctly retrieves and sends fresh tokens. -
TypeError: Cannot read properties of undefined (reading 'YOUR_KV_NAMESPACE')
cause The `KVNamespace` object was not provided to the `CloudFireAuth` constructor when it was expected, or `env` is not correctly passed/typed in your Worker handler.fixIf you intend to use KV caching, ensure `env.YOUR_KV_NAMESPACE` (or whatever your KV binding is named) is correctly passed as the second argument to `new CloudFireAuth()`. If not using KV, ensure the constructor is called without the second argument, or explicitly with `undefined`.
Warnings
- gotcha Cloudfire Auth is ESM-only. Attempting to import it using CommonJS `require()` will result in a runtime error.
- gotcha Not all Firebase Admin SDK methods are currently implemented. Several authentication and user management methods are marked with '❌' in the API reference (e.g., `verifySessionCookie`, `createCustomToken`, `createUser`, `getUserByEmail`, `deleteUsers`).
- gotcha The `serviceAccountKey` must be correctly formatted. When loading from environment variables, private keys with newline characters (e.g., `-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----`) must have these newlines preserved or correctly replaced (e.g., using `.replace(/\\n/g, '\n')`).
Install
-
npm install cloudfire-auth -
yarn add cloudfire-auth -
pnpm add cloudfire-auth
Imports
- CloudFireAuth
const CloudFireAuth = require('cloudfire-auth');import { CloudFireAuth } from 'cloudfire-auth'; - ServiceAccountKey
import type { ServiceAccountKey } from 'cloudfire-auth/types'; - KVNamespace
declare const env: { YOUR_KV_NAMESPACE?: KVNamespace }; // In Workers environment const auth = new CloudFireAuth(serviceAccountKey, env.YOUR_KV_NAMESPACE);
Quickstart
import { CloudFireAuth } from "cloudfire-auth";
interface Env {
YOUR_KV_NAMESPACE?: KVNamespace;
FIREBASE_PRIVATE_KEY: string;
FIREBASE_CLIENT_EMAIL: string;
// ... other service account fields as environment variables
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
// It is best practice to store your service account key separately and
// load it from a secure source, e.g., environment variables.
const serviceAccountKey = {
private_key: env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'), // Handle newline characters if from env
client_email: env.FIREBASE_CLIENT_EMAIL,
// Add other necessary fields from your Firebase service account key
// For example, project_id, type, private_key_id, etc.
// Ensure the structure matches ServiceAccountKey type.
};
// Initialize with your Firebase project credentials
const auth = new CloudFireAuth(
serviceAccountKey,
env.YOUR_KV_NAMESPACE // Optional: KV namespace for token caching
);
const idToken = request.headers.get('Authorization')?.split('Bearer ')[1];
if (!idToken) {
return new Response('No ID token provided', { status: 401 });
}
// Verify an ID token
try {
const decodedToken = await auth.verifyIdToken(idToken);
console.log("User ID:", decodedToken.uid);
return new Response(`Verified user: ${decodedToken.uid}`, { status: 200 });
} catch (error: any) {
console.error("Token verification failed:", error.message);
return new Response(`Token verification failed: ${error.message}`, { status: 401 });
}
},
};