คีย์ API เปรียบเสมือนกุญแจประตูหน้าของบริการของคุณ ซึ่งช่วยให้ผู้ใช้เข้าไปได้ในขณะที่รักษาความปลอดภัย ในบล็อกนี้ ฉันจะแนะนำคุณเกี่ยวกับการสร้างตัวสร้างคีย์ API ที่เรียบง่ายและปลอดภัยโดยใช้ Upstash Redis เพื่อการจัดเก็บข้อมูลที่รวดเร็วแบบไร้เซิร์ฟเวอร์ และ Cloudflare Workers เพื่อจัดการคำขอที่ Edge ไม่ว่าคุณจะตั้งค่าบริการใหม่หรือเพิ่มคีย์ลงในแอปที่มีอยู่ คุณจะได้เรียนรู้วิธีสร้าง จัดเก็บ และตรวจสอบคีย์ API เพื่อให้ทุกอย่างทำงานได้อย่างราบรื่นและมีประสิทธิภาพ
คีย์ API คืออะไร
คีย์ API คือรหัสเฉพาะที่ระบุและตรวจสอบสิทธิ์ผู้ใช้หรือแอปพลิเคชันที่พยายามเข้าถึง API ของคุณ ให้คิดว่ามันเหมือนกับบัตรผ่านส่วนตัว เมื่อมีคนต้องการใช้บริการของคุณ พวกเขาจะต้องแสดง "รหัส" นี้เพื่อพิสูจน์ว่าได้รับอนุญาต คีย์ API ช่วยให้คุณควบคุมผู้ที่สามารถเข้าถึงทรัพยากรของคุณได้ และมักใช้เพื่อติดตามการใช้งาน บังคับใช้ขีดจำกัด หรือป้องกันการเข้าถึงที่ไม่ได้รับอนุญาต เป็นวิธีที่ตรงไปตรงมาในการจัดการการเข้าถึง API และรักษาข้อมูลของคุณให้ปลอดภัย
สิ่งที่เราจะสร้าง
ในคู่มือนี้ เราจะสร้างตัวสร้างคีย์ API ที่มีฟังก์ชันหลักสองฟังก์ชัน:
- การสร้างคีย์ API ใหม่ด้วยการตั้งค่าที่กำหนดเอง
- การตรวจสอบความถูกต้องของคีย์ API ในขณะที่ดึงข้อมูลเมตาของพวกเขา
คุณสมบัติที่สำคัญจะรวมถึง:
- คำนำหน้าคีย์ที่ปรับแต่งได้
- วันหมดอายุ
- การจำกัดอัตรา
- การจัดเก็บข้อมูลเมตา
- บัตรประจำตัวเจ้าของ
เรามาเห็นภาพระบบคีย์ API ของเรากัน
แผนภาพนี้แสดงการโต้ตอบระหว่างไคลเอนต์, Cloudflare Worker ของเรา และ Upstash Redis สำหรับทั้งการสร้างและการตรวจสอบคีย์ API เมื่อคำนึงถึงภาพรวมนี้แล้ว มาเริ่มสร้างระบบของเรากันดีกว่า

ข้อกำหนดเบื้องต้น
หากต้องการติดตาม คุณจะต้องมี:
- ผู้ปฏิบัติงาน Cloudflare บัญชี
- สุดยอด บัญชี
- Node.js ติดตั้งอยู่บนเครื่องของคุณ
โครงสร้างโครงการ
โครงการของเราจะมีโครงสร้างดังต่อไปนี้:
folder-name/
├── src/
│ ├── config/
│ │ ├── generateApiKey.ts
│ │ └── schema-validation.ts
│ ├── lib/
│ │ └── ratelimit.ts
│ ├── routes/
│ │ ├── create.ts
│ │ └── verify.ts
│ ├── types/
│ │ └── api.ts
│ └── index.ts
├── package.json
└── wrangler.toml
ขั้นตอนที่ 1:การตั้งค่าโครงการ
เริ่มต้นด้วยการตั้งค่าโปรเจ็กต์ของเราและติดตั้งการขึ้นต่อกันที่จำเป็น
สร้างไดเรกทอรีโครงการใหม่
เปิดเทอร์มินัลของคุณและรันคำสั่งต่อไปนี้:
mkdir keyflow
cd keyflow
npm init -y ติดตั้งการอ้างอิง
เราจะต้องมีแพ็คเกจบางส่วนสำหรับโครงการของเรา:
npm install hono @upstash/redis @upstash/ratelimit @hono/zod-validator zod wrangler
00รหัส> :Upstash Redis ไคลเอ็นต์สำหรับสภาพแวดล้อมแบบไร้เซิร์ฟเวอร์15 :ไลบรารีจำกัดอัตราสำหรับ Upstash Redis22 :ขอมิดเดิลแวร์ตรวจสอบสำหรับ Hono32 :ไลบรารีการตรวจสอบสคีมาแรกของ TypeScript41 :CLI ของ Cloudflare สำหรับการพัฒนาและการปรับใช้ของผู้ปฏิบัติงาน
ตั้งค่า Upstash Redis
- ลงชื่อเข้าใช้บัญชี Upstash ของคุณและสร้างฐานข้อมูล Redis ใหม่

- เมื่อสร้างแล้ว ให้ไปที่ส่วน "REST API"

- คัดลอก
54และ64ใน78ส่วน
กำหนดค่าผู้ปฏิบัติงาน Cloudflare
สร้าง 82 ในรูทโปรเจ็กต์ของคุณโดยมีเนื้อหาดังต่อไปนี้:
name = "keyflow"
main = "src/index.ts"
compatibility_date = "2023-05-18"
[vars]
UPSTASH_REDIS_REST_URL = "your-redis-url"
UPSTASH_REDIS_REST_TOKEN = "your-redis-token"
แทนที่ 97 และ 108 ด้วยค่าที่คุณคัดลอกมาจาก Upstash
ขั้นตอนที่ 2:การกำหนดประเภท API
เริ่มต้นด้วยการกำหนดอินเทอร์เฟซ TypeScript สำหรับคำขอและการตอบกลับ API ของเรา ประเภทเหล่านี้จะช่วยให้เรารักษาความปลอดภัยของประเภทตลอดการใช้งานของเรา สร้างไฟล์ใหม่ 117 :
export type CreateKeyRequest = {
apiId: string;
prefix?: string;
byteLength?: number;
ownerId?: string;
name: string;
meta?: Record<string, unknown>;
expires?: number;
ratelimit?: {
type: "fast" | "consistent";
limit: number;
refillRate: number;
refillInterval: number;
};
};
export type CreateKeyResponse = {
key: string;
keyId: string;
};
export type VerifyKeyRequest = {
key: string;
};
export type VerifyKeyResponse = {
valid: boolean;
ownerId?: string;
meta?: Record<string, unknown>;
expires?: number;
ratelimit?: {
limit: number;
remaining: number;
reset: number;
};
};
export type Env = {
UPSTASH_REDIS_REST_URL: string;
UPSTASH_REDIS_REST_TOKEN: string;
};
ขั้นตอนที่ 3:การใช้การสร้างคีย์ API
ตอนนี้ เรามาสร้างฟังก์ชันยูทิลิตี้เพื่อสร้างคีย์ API ของเรากันดีกว่า สร้างไฟล์ใหม่ 120 :
export function generateApiKey(
prefix: string | undefined,
byteLength: number,
): string {
const randomBytes = crypto.getRandomValues(new Uint8Array(byteLength));
const key = btoa(String.fromCharCode(...new Uint8Array(randomBytes)))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "");
return prefix ? `${prefix}_${key}` : key;
}
ฟังก์ชันนี้สร้างคีย์ API แบบสุ่มโดยใช้ไบต์สุ่มที่ปลอดภัยด้วยการเข้ารหัส เข้ารหัสใน base64 และทำให้ URL ปลอดภัย
ขั้นตอนที่ 4:การจำกัดอัตราการใช้งาน
สร้างไฟล์ 130 :
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis/cloudflare";
import type { Context, Next } from "hono";
import { env } from "hono/adapter";
import type { Env } from "../types/api";
// Middleware for rate limiting
export async function rateLimitMiddleware(c: Context, next: Next) {
const { UPSTASH_REDIS_REST_TOKEN, UPSTASH_REDIS_REST_URL } = env<Env>(c);
const redis = new Redis({
url: UPSTASH_REDIS_REST_URL,
token: UPSTASH_REDIS_REST_TOKEN,
});
const ratelimit = new Ratelimit({
redis: redis,
limiter: Ratelimit.slidingWindow(5, "30 s"),
});
const ip = c.req.header("CF-Connecting-IP") || "127.0.0.1";
const { success, limit, remaining, reset } = await ratelimit.limit(ip);
if (!success) {
return c.json({ error: "Rate limit exceeded" }, 429);
}
c.header("X-RateLimit-Limit", limit.toString());
c.header("X-RateLimit-Remaining", remaining.toString());
c.header("X-RateLimit-Reset", reset.toString());
await next();
} ขั้นตอนที่ 5:การสร้างเส้นทาง API
มาตั้งค่าไฟล์แอปพลิเคชันหลักของเราและสร้างเส้นทาง API ของเรา ไฟล์นี้ตั้งค่าแอปพลิเคชัน Hono ของเราด้วยสองเส้นทางหลัก: 143 สำหรับการสร้างคีย์ API ใหม่และ 157 สำหรับตรวจสอบคีย์ที่มีอยู่ด้วยไฟล์แยกกันสามไฟล์
1. ใช้งานสร้างเส้นทางคีย์ API
สร้างไฟล์ 167 :
import { zValidator } from "@hono/zod-validator"
import { Redis } from "@upstash/redis/cloudflare"
import { Hono } from "hono"
import { generateApiKey } from "../config/generateApiKey"
import { createApiKeySchema } from "../config/schema-validation"
import type { CreateKeyRequest, CreateKeyResponse, Env } from "../types/api"
const create = new Hono<{
Bindings: Env
}>()
create.post(
"/create",
zValidator("json", createApiKeySchema, (result, c) => {
if (!result.success) {
return c.text("Invalid!", 400)
}
}),
async (c) => {
// Initialize Redis client
const { UPSTASH_REDIS_REST_TOKEN, UPSTASH_REDIS_REST_URL } = c.env
const redis = new Redis({
url: UPSTASH_REDIS_REST_URL,
token: UPSTASH_REDIS_REST_TOKEN,
})
const body = await c.req.json<CreateKeyRequest>()
// Generate unique identifier and API key
const keyId = crypto.randomUUID()
const key = generateApiKey(body.prefix, body.byteLength || 16)
const keyData = {
...body,
key,
keyId,
createdAt: Date.now(),
}
const encodedKey = encodeURIComponent(key)
try {
// Store key data and lookup reference in Redis
await redis.set(`key:${keyId}`, JSON.stringify(keyData))
await redis.set(`lookup:${encodedKey}`, keyId)
return c.json<CreateKeyResponse>({ key, keyId })
} catch (error) {
console.error("Error in /keys/create:", error)
return c.json({ error: "Internal Server Error" }, 500)
}
}
)
export default create 2. ใช้ตรวจสอบเส้นทางคีย์ API
สร้างไฟล์ 179 :
import { zValidator } from "@hono/zod-validator";
import { Redis } from "@upstash/redis/cloudflare";
import { Hono } from "hono";
import { verifyApiKeySchema } from "../config/schema-validation";
import type {
CreateKeyRequest,
Env,
VerifyKeyRequest,
VerifyKeyResponse,
} from "../types/api";
// Initialize Hono app with environment bindings
const verify = new Hono<{ Bindings: Env }>();
// Define POST route for verifying an API key
verify.post(
"/verify",
// Validate request body against schema
zValidator("json", verifyApiKeySchema, (result, c) => {
if (!result.success) {
return c.text("Invalid!", 400); // Return 400 if validation fails
}
}),
async (c) => {
// Set up Redis with environment variables
const { UPSTASH_REDIS_REST_TOKEN, UPSTASH_REDIS_REST_URL } = c.env;
const redis = new Redis({
url: UPSTASH_REDIS_REST_URL,
token: UPSTASH_REDIS_REST_TOKEN,
});
const body = await c.req.json<VerifyKeyRequest>();
if (!body.key) {
return c.json({ error: "key is required" }, 400); // Require key in the request body
}
const encodedKey = encodeURIComponent(body.key);
const keyId = await redis.get<string>(`lookup:${encodedKey}`); // Retrieve key ID using encoded key
if (!keyId) {
return c.json<VerifyKeyResponse>({ valid: false }); // Key not found
}
const keyDataString = await redis.get<string>(`key:${keyId}`); // Retrieve key data by key ID
if (!keyDataString || typeof keyDataString !== "string") {
return c.json<VerifyKeyResponse>({ valid: false }); // Key data missing or invalid
}
let keyData: CreateKeyRequest & {
key: string;
keyId: string;
createdAt: number;
};
try {
keyData = JSON.parse(keyDataString); // Parse key data
} catch (parseError) {
// Handle parse error by deleting invalid data
console.error("Key data parse error:", parseError);
await Promise.all([
redis.del(`key:${keyId}`),
redis.del(`lookup:${encodedKey}`),
]);
return c.json(
{
error: "Invalid key data in storage",
details: parseError instanceof Error ? parseError.message : "Unknown parse error",
valid: false,
},
500,
);
}
// Check if key has expired
if (keyData.expires && keyData.expires < Date.now()) {
await Promise.all([
redis.del(`key:${keyId}`),
redis.del(`lookup:${encodedKey}`),
]);
return c.json<VerifyKeyResponse>({ valid: false });
}
// Formulate response with validation status and metadata
const response: VerifyKeyResponse = {
valid: true,
ownerId: keyData.ownerId,
meta: keyData.meta,
expires: keyData.expires,
};
if (keyData.ratelimit) {
response.ratelimit = {
limit: keyData.ratelimit.limit,
remaining: keyData.ratelimit.limit,
reset: Date.now() + keyData.ratelimit.refillInterval,
};
}
return c.json(response); // Return verification response
},
);
export default verify;
3. ใช้งานไฟล์หลักindex.ts
ใช้ไฟล์หลัก
ปรับใช้แอปพลิเคชัน Keyflow ของคุณกับ Cloudflare Workers:
ติดตั้งแรงเลอร์:
ตรวจสอบสิทธิ์กับ Cloudflare:
ปรับใช้พนักงานของคุณ:
ตอนนี้เรามีแอปพลิเคชันของเราพร้อมแล้ว เรามาปรับใช้กับ Cloudflare Workers กันดีกว่า:
ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง Wrangler CLI แล้ว:
ตรวจสอบสิทธิ์กับบัญชี Cloudflare ของคุณ:
ปรับใช้พนักงานของคุณ:
มาทดสอบ API ที่เพิ่งปรับใช้ใหม่ของเรากัน:
แทนที่
การสร้างตัวสร้างคีย์ API เป็นขั้นตอนสำคัญในการรักษาความปลอดภัย API ของแอปพลิเคชันของคุณและการจัดการผู้ที่สามารถเข้าถึงบริการของคุณได้ ด้วยการสร้างระบบที่สามารถสร้าง ตรวจสอบ และจัดการคีย์ API คุณจะเพิ่มการควบคุมการเข้าถึงอีกชั้นที่แข็งแกร่งซึ่งจะช่วยรักษาข้อมูลของคุณให้ปลอดภัยและเป็นระเบียบ
ต่อไปนี้เป็นบทสรุปโดยย่อเกี่ยวกับสิ่งที่รวมอยู่ในตัวสร้างคีย์ API ที่แข็งแกร่ง:
การใช้เครื่องมืออย่าง Upstash Redis และ Cloudflare Workers ทำให้การสร้างระบบการจัดการคีย์แบบไร้เซิร์ฟเวอร์และกระจายไปทั่วโลกเป็นเรื่องง่าย ซึ่งปรับขนาดได้ดีและทำงานอย่างมีประสิทธิภาพ
ด้วยรากฐานนี้ คุณพร้อมที่จะรักษาการเข้าถึง API ของคุณให้ปลอดภัยและสามารถจัดการได้ ทำให้คุณอุ่นใจได้ว่าทรัพยากรของคุณจะได้รับการปกป้องและง่ายต่อการตรวจสอบ181 เพื่อนำเข้า 190 , 206รหัส> และ 219 ป> import { Hono } from "hono";
import { rateLimitMiddleware } from "./lib/ratelimit";
import create from "./routes/create";
import verify from "./routes/verify";
import type { Env } from "./types/api";
const app = new Hono<{
Bindings: Env;
}>().basePath("/keys");
app.use("*", rateLimitMiddleware);
// add the create file route and verify file route
app.route("/", create);
app.route("/", verify);
export default app;
ขั้นตอนที่ 6:การปรับใช้
npm install -g wranglerwrangler loginwrangler deployขั้นตอนที่ 7:การปรับใช้
npm install -g wrangler
wrangler login
wrangler deploy
ขั้นตอนที่ 8:ทดสอบ API ของคุณ
การสร้างคีย์ API ใหม่
curl -X POST https://keyflow.<your-subdomain>.workers.dev/keys/create \
-H "Content-Type: application/json" \
-d '{
"apiId": "my-api",
"prefix": "prod",
"name": "Production API Key",
"expires": 1735689600000,
"meta": {
"environment": "production",
"team": "backend"
}
}'
การตรวจสอบคีย์ API
curl -X POST https://keyflow.<your-subdomain>.workers.dev/keys/verify \
-H "Content-Type: application/json" \
-d '{
"key": "prod_AbC123XyZ..."
}'
222 ด้วยโดเมนย่อย Cloudflare Workers ของคุณและ 236 ด้วยคีย์จริงที่สร้างจากจุดสิ้นสุดการสร้างบทสรุป