امنیت API Key در فرانتاند؛ چرا کلید وبسرویس را در جاوااسکریپت و اپ نگذارید
امنیت API Key در فرانتاند و موبایل: چرا کلید در مرورگر لو میرود، پروکسی سمت سرور، محدودیت IP و دامنه، متغیرهای محیطی، چرخش کلید و جلوگیری از انتشار در گیت.

- هر چیزی که به مرورگر یا اپ برسد، قابل خواندن است؛ کلید API در جاوااسکریپت یا فایل APK امن نیست.
- الگوی درست، پروکسی سمت سرور است: مرورگر از سرور شما میخواند و فقط سرور کلید را دارد.
- محدودیت IP، کلید جدا برای هر پروژه، متغیر محیطی و اسکن خودکار مخزن کد، لایههای بعدی دفاعاند.
یکی از رایجترین پیامهایی که پشتیبانی هر وبسرویسی دریافت میکند این است: سهمیهام در یک روز تمام شد، در حالی که سایتم بازدید زیادی ندارد. تقریبا همیشه علت یکی است: کلید در کد سمت مرورگر بوده و کس دیگری از آن استفاده کرده است. در این مقاله امنیت API Key را در پروژههای فرانتاند و موبایل بررسی میکنیم.
این مقاله بخشی از آموزش API قیمت ارز و طلا است.
کلید در مرورگر چطور لو میرود؟
فرض کنید کد زیر را در صفحه گذاشتهاید:
// ❌ اشتباه: کلید در کد سمت مرورگر
fetch("https://api.ezrate.me/v1/rates?symbols=usd", {
headers: { "X-API-Key": "ezr_live_abc123…" } })هر بازدیدکنندهای با فشار دادن F12 و رفتن به تب Network، همین درخواست و هدر آن را میبیند. حتی اگر کد را مبهمسازی (Obfuscate) کنید، کلید هنگام ارسال درخواست بهصورت خوانا در هدر است. رباتهایی هم وجود دارند که صفحههای وب و مخزنهای گیتهاب را برای الگوی کلیدهای شناختهشده اسکن میکنند.
در اپ موبایل هم وضع بهتر نیست. فایل APK با ابزارهای رایگان باز میشود و رشتههای داخل کد خوانده میشود. ذخیره در فایل تنظیمات یا رمزنگاری با کلیدی که آن هم داخل اپ است، فقط کار را کمی سختتر میکند، نه غیرممکن.
الگوی درست: پروکسی سمت سرور
مرورگر یا اپ از یک مسیر روی سرور شما میخواند. سرور کلید را دارد، درخواست را به API میفرستد، پاسخ را کش میکند و فقط دادهٔ لازم را برمیگرداند. این الگو دو مزیت دیگر هم دارد: تعداد درخواست به API به تعداد کاربران وابسته نیست و میتوانید فقط فیلدهای لازم را به کلاینت بدهید.
نمونه با Cloudflare Workers (رایگان و بدون سرور)
// worker.js — کلید در Secrets ورکر: wrangler secret put EZRATE_KEY
export default {
async fetch(request, env, ctx) {
const cache = caches.default
const key = new Request("https://cache.local/rates")
let res = await cache.match(key)
if (!res) {
const api = await fetch("https://api.ezrate.me/v1/rates?symbols=usd,eur,g18,emami,usdt", {
headers: { "X-API-Key": env.EZRATE_KEY } })
if (!api.ok) return new Response("upstream error", { status: 502 })
res = new Response(await api.text(), {
headers: { "Content-Type": "application/json", "Cache-Control": "public, max-age=60",
"Access-Control-Allow-Origin": "https://your-site.com" } })
ctx.waitUntil(cache.put(key, res.clone()))
}
return res
},
}نمونه همین پروکسی در Next.js (Route Handler) در تابلو قیمت طلا با React، در لاراول در دریافت نرخ ارز در PHP و در وردپرس در نمایش قیمت ارز در وردپرس آمده است.
Access-Control-Allow-Origin را روی دامنهٔ همان سایت بگذارید، نه *. اینطور سایتهای دیگر نمیتوانند از مرورگر کاربرانشان پروکسی شما را مصرف کنند.لایههای دفاعی بعدی
| لایه | چه کاری | در برابر چه خطری |
|---|---|---|
| محدودیت IP | کلید فقط از IP سرور شما پذیرفته شود | استفاده از کلید دزدیدهشده در جای دیگر |
| کلید جدا برای هر پروژه | سایت، اپ و اسکریپت داخلی هر کدام کلید خود را داشته باشند | باطل کردن یک کلید بدون از کار افتادن بقیه |
| متغیر محیطی | کلید در .env یا Secrets هاست | انتشار کلید با کد |
.gitignore | فایل .env هرگز commit نشود | لو رفتن در گیتهاب |
| اسکن خودکار مخزن | ابزارهایی مثل gitleaks در CI | commit تصادفی کلید |
| چرخش دورهای | هر چند ماه کلید جدید و باطل کردن قبلی | کلیدی که بیخبر لو رفته |
| پایش مصرف | بررسی GET /usage و هشدار مصرف غیرعادی | کشف زودهنگام سوءاستفاده |
اگر کلید لو رفت، چه کنیم؟
- در پنل کاربری فورا کلید جدید بسازید و در سرور جایگزین کنید.
- کلید قدیمی را باطل کنید. از این لحظه درخواستهای با آن کلید خطای 401 میگیرند.
- اگر کلید در گیتهاب commit شده، حذف فایل کافی نیست؛ کلید در تاریخچه گیت باقی است. باطل کردن کلید تنها راه مطمئن است.
- علت را پیدا کنید: کلید در کد کلاینت بود؟ در لاگ چاپ میشد؟ در اسکرینشاتی منتشر شد؟
برای نمایش ساده، اصلاً کلید لازم نیست
اگر فقط میخواهید قیمت را در صفحه نشان دهید، ویجتهای قیمت بدون کلید کار میکنند و داده را از یک مسیر عمومی و کششده میخوانند. خطر لو رفتن کلید وقتی پیش میآید که کسی برای یک نمایش ساده سراغ API میرود.
نسخه انگلیسی با تمرکز بر اپهای موبایل در Securing Financial API Keys آمده است.

نظرات (۰)
نظرها پس از تأیید نمایش داده میشوند؛ برای ارسال، ورود به حساب لازم است.


