Appearance
Protect API Route with verifyIdToken
This guide shows you how to protect API routes in SvelteKit using cloudfire-auth to verify Firebase ID tokens on the server-side.
Installation
Install cloudfire-auth with:
bash
npm install cloudfire-authSetup
1. Create Server Auth Module
Create a server-side authentication module. In SvelteKit, everything within the src/lib/server directory is never sent to the client.
Create the following file structure:
📁 src/
├── 📁 lib/
│ ├── 📁 server/
│ │ ├── 📄 auth.tsAdd the following code to src/lib/server/auth.ts:
typescript
import { CloudFireAuth } from "cloudfire-auth";
import { base64url } from "jose";
import { FIREBASE_SERVICE_ACCOUNT_KEY } from "$env/static/private";
import type { KVNamespace } from "@cloudflare/workers-types";
/**
* Create a new CloudFireAuth instance from a service account key you have
* stored in your environment variables.
* @param kvNamespace KV namespace to use for the auth instance.
* @returns CloudFireAuth instance.
*/
export function getServerAuth(kvNamespace: KVNamespace) {
const decodedKey = base64url.decode(FIREBASE_SERVICE_ACCOUNT_KEY);
const serviceAccountJsonString = new TextDecoder().decode(decodedKey);
const serviceAccountKey = JSON.parse(serviceAccountJsonString);
return new CloudFireAuth(serviceAccountKey, kvNamespace);
}2. Understanding the Setup
getServerAuth- This is the core exported function that creates a new instance ofCloudFireAuthfor interacting with your Firebase project.kvNamespace- This is a KV Namespace you need to attach to your Cloudflare project. It adds caching to yourCloudFireAuthinstance, improving performance.serviceAccountKey- The service account key associated with your Firebase project. This example stores it as a base64-encoded string in an environment variable, but as long as the key is passed in as a JavaScript object, it will work correctly.CloudFireAuth- The returned instance that lets you interact with your Firebase Authentication repository.
Note: It's safe to put your service account key in an environment variable like
FIREBASE_SERVICE_ACCOUNT_KEY, because any.envvariable without aPUBLIC_prefix is private by default in SvelteKit.
Protecting an API Endpoint
To protect an API endpoint, create a route handler that verifies the Firebase ID token before processing the request.
1. Create the API Route
Create a new API route:
bash
touch src/routes/api/check-auth/+server.ts2. Implement Token Verification
Paste this into your +server.ts file:
typescript
import { json } from "@sveltejs/kit";
import type { RequestHandler } from "@sveltejs/kit";
import { getServerAuth } from "$lib/server/auth";
export const GET: RequestHandler = async ({ request, platform }) => {
try {
// Extract the token from the cookie
const cookie = request.headers.get("cookie");
const token = cookie?.split("firebase-token=")[1];
if (!token) {
return json({ error: "No token provided" }, { status: 401 });
}
// Get the server auth instance
const serverAuth = getServerAuth(platform?.env?.KV);
// Verify the ID token
// If the token is invalid, an error will be thrown
const idToken = await serverAuth.verifyIdToken(token);
// Token is valid, proceed with the request
return json(
{
message: "You are authorised",
uid: idToken.uid,
},
{ status: 200 }
);
} catch (error) {
console.error("Error processing request:", error);
return json({ error: "You are not authorised" }, { status: 401 });
}
};3. How It Works
- Extract the token - The code extracts the Firebase ID token from the
firebase-tokencookie in the request headers. - Get auth instance - Creates a
CloudFireAuthinstance using the KV namespace from your Cloudflare platform environment. - Verify the token - Calls
verifyIdToken()which validates the token signature, expiration, and issuer. If the token is invalid, an error is thrown. - Handle the response - If verification succeeds, the request is authorized and you can proceed. If it fails, a 401 Unauthorized response is returned.
4. Using the Protected Endpoint
When making requests to this endpoint, ensure the Firebase ID token is included in the firebase-token cookie. The client should set this cookie after successful authentication.
Additional Notes
- The
verifyIdToken()method automatically handles token validation, including checking expiration and signature verification. - If you're using a KV namespace, the public signing keys are cached, making subsequent verifications much faster.
- You can access the decoded token claims (like
uid,email, etc.) from theidTokenobject returned byverifyIdToken(). - This same pattern can be used for other HTTP methods (POST, PUT, DELETE, etc.) by exporting the corresponding handler functions.