06.05 — isAuthorized.ts#
Source file:
lib/isAuthorized.tsVerifies that a request contains the right
x-api-key.
Code#
import type { NextRequest } from "next/server";
const API_SECRET = process.env.API_SECRET;
function isAuthorized(request: NextRequest): boolean {
if (typeof API_SECRET !== "string") {
console.error("[CONFIG ERROR] API_SECRET is not defined");
return false;
}
const { searchParams } = new URL(request.url);
const apiKey = searchParams.get("apiKey") ?? request.headers.get("x-api-key");
return apiKey === API_SECRET;
}
export default isAuthorized;Approach#
1. API_SECRET#
const API_SECRET = process.env.API_SECRET;Read once at Edge worker startup (cold start), stored as a module variable. Faster than hitting process.env on every call.
2. typeof !== "string" guard#
if (typeof API_SECRET !== "string") {
console.error("[CONFIG ERROR] API_SECRET is not defined");
return false;
}Undefined env var → log + refuse. No startup panic. Fail-safe: auth is refused, so a missing env var can’t be exploited.
3. Key passing#
const apiKey = searchParams.get("apiKey") ?? request.headers.get("x-api-key");- Query string
?apiKey=<X>. - Header
x-api-key: <X>(fallback).
| Case | Where |
|---|---|
| cURL | Query string (simpler, no need for -H) |
| Production / browser fetch | Header (best practice, doesn’t show in server logs) |
The README documents both:
curl -H "x-api-key: SECRET" "https://.../api/otp"
curl "https://.../api/otp?apiKey=SECRET" # same thingExport/import#
export default isAuthorized;import isAuthorized from "../lib/isAuthorized";No rate-limit#
No rate-limiting. An attacker with the right API_SECRET could spam — but they’d need the secret first, and the Vercel Free Tier caps requests at ~100 req/s anyway. Application-level rate-limiting isn’t needed here.
console.error#
console.error("[CONFIG ERROR] API_SECRET is not defined");console.* in an Edge Function shows up in the Vercel dashboard logs. If API_SECRET is undefined, the maintainer sees it immediately.