پرش به محتوا
طراحی سایت

احراز هویت API؛ کلید API یا توکن JWT کدام را انتخاب کنیم؟

۱۲ دقیقه مطالعه

اگر بین کلید API و JWT مردد هستید، جواب کوتاه این است: برای سرویس های ثابت کلید کافی است و برای کاربران با حساب شخصی JWT مناسب تر است. در این نوشته احراز هویت API را با چند معیار روشن مقایسه کرده ایم.

مقایسه دو جریان احراز هویت: یک کلید ثابت در برابر ورود و توکن کوتاه عمر

اگه می خوای بدونی برای API پروژه ات کلید API بذاری یا JWT، جواب کوتاه اینه: وقتی برنامه ها یا سرویس های مشخصی صداش می زنن (مثلاً اتصال فروشگاه به پنل پیامک)، کلید API ساده تر و کافیه. وقتی کاربرهای واقعی با حساب شخصی وارد می شن (مثل اپلیکیشن موبایل یا پنل کاربری)، JWT مناسب تره. تو خیلی از پروژه ها هم هر دو کنار هم می شینن. تو این نوشته احراز هویت API رو با چند معیار مشخص مقایسه می کنیم و برای هر نوع کاربر یه توصیه روشن می دیم.

این دو روش اصلاً یه سؤال رو جواب نمی دن

کلید API می گه «کدوم برنامه یا مشتری داره درخواست می ده». JWT می گه «کدوم کاربر، با چه دسترسی و تا چه زمانی».

یه تشبیه بزنم. کلید API مثل کلید فیزیکی آپارتمانه: هرکی داشته باشه وارد می شه، تا وقتی که قفل رو عوض نکنی. JWT مثل کارت اتاق هتله: بعد از شناسایی تو پذیرش صادر می شه، اتاق و تاریخ انقضا داره و بعد از خروج دیگه به درد نمی خوره.

پس این مقایسه در اصل مقایسه دو نوع اعتماده: اعتماد ثابت به یه برنامه، یا اعتماد موقت به یه نشست. JWT معمولاً بعد از مرحله ورود صادر می شه، چه با نام کاربری و رمز، چه با کد پیامکی. یعنی بدون سیستم ورود، اصلاً توکنی نداری که امضا کنی.

یه نکته که زیاد اشتباه برداشت می شه: JWT خودش رمزنگاری یا امنیت جادویی نیست. فقط یه قالب امضا شده برای ادعاهاست، مثل «این کاربر شماره ۱۸۴۲ و تا ساعت فلان معتبره». هرکس توکن رو ببینه محتواش رو می تونه بخونه، چون payload فقط با Base64url کدگذاری شده و رمز نشده. امضا فقط تضمین می کنه کسی محتوا رو دستکاری نکرده.

مقایسه جریان درخواست با کلید ثابت و جریان درخواست با توکن کوتاه عمر

مقایسه احراز هویت API، معیار به معیار

اول یه جمع بندی سریع، بعد هر معیار رو جدا باز می کنم.

معیارکلید APIJWT
سادگی پیاده سازیساده ترپیچیده تر
ابطال فوریآسون، یه رکورد رو غیرفعال می کنیسخت تر، بدون ذخیره سمت سرور تقریباً ممکن نیست
دقت دسترسیدر سطح برنامه یا مشتریدر سطح کاربر و نقش
عمر اعتباربلندکوتاه، با تمدید
بار روی دیتابیسیه جستجو در هر درخواست یا کشبررسی امضا، معمولاً بدون دیتابیس

کدوم روش ساده تر پیاده می شه؟

کلید API رو تو یه جدول ساده نگه می داری: شناسه مشتری، هش کلید، وضعیت، تاریخ ساخت. مصرف کننده هم فقط یه هدر می فرسته. منطق ورود، صفحه لاگین و مدیریت نشست لازم نداری.

JWT چند قطعه کار داره: endpoint ورود، امضای توکن، اعتبارسنجی در هر درخواست، مدیریت انقضا و معمولاً یه refresh token. هر قطعه یه جای ممکن برای خطاست. اگه تیم کوچیکی داری و API فقط برای یکی دو سرویس مشخصه، این بار اضافه معمولاً به نفعت نیست.

اگه کلید یا توکن لو بره چی می شه؟

کلیدی که لو بره تا وقتی دستی باطلش نکنی معتبر می مونه. ولی ابطالش آسونه: رکورد رو غیرفعال می کنی و همون لحظه از کار می افته.

JWT کوتاه عمر پنجره سوءاستفاده رو کوچیک می کنه. اگه توکن ۱۵ دقیقه عمر داشته باشه و کسی بدزدتش، فرصتش محدوده. ولی ابطال فوری یه توکن معتبر بدون فهرست سیاه یا ذخیره سمت سرور سخته. سرور فقط امضا رو چک می کنه و نمی دونه کاربر الان بن شده یا نه. اگه فهرست سیاه بذاری، عملاً دوباره به چک کردن تو دیتابیس برگشتی. اشکالی نداره، فقط بدون که داری مزیت stateless بودن رو کم می کنی.

نکته مهم تر، جایی که کلید یا توکن سمت کلاینت نگه داشته می شه. کلید API تو کد فرانت اند مرورگر یعنی کلید عمومی؛ هر کسی با باز کردن Network تو DevTools می بینتش. JWT هم اگه تو localStorage باشه، با یه حفره XSS می ره. برای وب معمولاً کوکی HttpOnly و Secure امن تره.

دسترسی تا کجا ریز می شه؟

کلید API معمولاً می گه «این مشتری به این بخش ها دسترسی داره». می تونی scope هم بهش بدی (مثلاً فقط خوندن سفارش ها)، ولی هنوز دسترسی برنامه رو مشخص می کنه، نه کاربر نهایی رو.

JWT ادعاها رو خودش حمل می کنه: شناسه کاربر، نقش، شاید شناسه فروشگاهش. سرور بدون پرس وجو می دونه کاربر مدیره یا مشتری عادی. هرچی دسترسی ها ریزتر و وابسته به کاربر باشن، JWT راحت تر جواب می ده.

فشار روی سرور و دیتابیس

بررسی کلید API یعنی یه جستجو تو دیتابیس یا کش. با Redis یا حتی کش داخل حافظه، این هزینه ناچیزه. بررسی JWT فقط محاسبه امضاست و به دیتابیس نمی خوره.

تفاوت وقتی حس می شه که ترافیک بالاست، مثلاً شب های کمپین فروش، و دیتابیس اصلی هم درگیر سفارش ها و پرداخته. ولی اگه کش رو درست بذاری، برای خیلی از کسب و کارهای کوچک و متوسط گلوگاه اصلی یه جای دیگه پیدا می شه.

کدوم سناریو، کدوم روش

چند سناریوی رایج رو بر اساس نوع کاربر جدا کردم.

فروشگاه ووکامرس و اتصال به سرویس های بیرونی

فروشگاهت می خواد از پنل پیامک یا سیستم انبار داده بگیره. اینجا کاربر انسانی وسط نیست و سرور با سرور حرف می زنه. کلید API انتخاب درسته. کلیدی که از سرویس بیرونی گرفتی رو تو تنظیمات رمزنگاری شده ذخیره کن و هیچ وقت تو صفحه نشونش نده. فیلد کلید هم خالی بمونه و فقط مقدار جدید رو قبول کنه، تا مدیر سایت بتونه راحت عوضش کنه.

اپلیکیشن موبایل یا پنل کاربری

اینجا هر کاربر حساب خودش رو داره و نباید به اطلاعات دیگران برسه. JWT یا یه نشست مشابه لازمه. تو موبایل توکن رو تو Keychain (iOS) یا Keystore (اندروید) نگه دار، نه تو فایل ساده. access token کوتاه عمر رو با یه refresh token جدا داشته باش، تا اگه گوشی گم شد بشه نشست رو ابطال کرد.

API عمومی برای توسعه دهنده های دیگه

وقتی بقیه روی API تو برنامه می سازن، کلید API رایج ترین راهه. هر توسعه دهنده یه کلید می گیره، سقف درخواست داره و می تونی مصرفش رو ببینی. اگه کاربرهای نهایی اون توسعه دهنده ها هم باید شناسایی بشن، لایه JWT یا OAuth کنارش میاد.

سرویس داخلی بین میکروسرویس ها

دو راه داری: کلید ثابت بین سرویس ها، یا JWT کوتاه عمری که یه سرویس مرکزی صادر می کنه. اگه سرویس ها کم و تحت کنترل خودتن، کلید ساده کافیه. اگه تعدادشون زیاده و می خوای دسترسی هر سرویس مشخص و موقت باشه، JWT منطقی تره.

وقتی هر دو رو با هم می خوای

خیلی از سیستم ها هر دو رو دارن. کلید API هویت برنامه رو مشخص می کنه و سقف درخواست می ذاره؛ JWT هویت کاربر داخل اون برنامه رو. مثلاً اپلیکیشن موبایل با یه کلید عمومی به API می رسه و برای کارهای حساس توکن کاربر رو هم می فرسته. این ترکیب اشکالی نداره، فقط یادت باشه کلید داخل اپ رمز نیست و نباید بهش اعتماد امنیتی کامل کنی.

معماری ترکیبی با دروازه API، بررسی توکن و ذخیره کلیدها

راه اندازی عملی، قدم به قدم و با دلیلش

کلید API رو درست بساز و نگه دار

کلید رو تصادفی و بلند بساز. حدس زدنی بودن بدترین اشتباهه.

KEY="wb_live_$(openssl rand -hex 24)"
echo "$KEY"
echo -n "$KEY" | sha256sum

خط اول کلید رو می سازه و پیشوند wb_live_ فقط شناسایی رو راحت تر می کنه (مثلاً تو لاگ و اسکنرهای افشای کلید). خط سوم هش کلید رو درمیاره.

کلید خام رو فقط یک بار به مشتری نشون بده و تو دیتابیس فقط هشش رو نگه دار. اگه دیتابیس لو بره، مهاجم از روی هش نمی تونه کلید معتبر بسازه. منطقش همون ذخیره رمز کاربره.

مصرف کننده کلید رو تو هدر می فرسته:

curl -H "X-API-Key: wb_live_xxxxxxxx" https://api.example.ir/v1/orders

کلید رو هیچ وقت تو URL نذار (مثل ?api_key=...). آدرس ها تو لاگ سرور، تاریخچه مرورگر و پروکسی ها ذخیره می شن.

برای هر کلید سقف درخواست بذار

حتی با کلید معتبر، بدون سقف درخواست یه اسکریپت خراب می تونه سرورت رو بخوابونه. با Nginx می شه روی هدر کلید محدودیت گذاشت:

limit_req_zone $http_x_api_key zone=apikey:10m rate=10r/s;

location /v1/ {
    limit_req zone=apikey burst=20 nodelay;
    proxy_pass http://127.0.0.1:3000;
}

دستور limit_req_zone تو بلاک http میاد و limit_req تو location. عدد 10r/s فقط برای نمونه گذاشته شده، با ظرفیت واقعی سرورت تنظیمش کن. یه نکته هم هست: درخواستی که هدر کلید نداره، مقدار کلیدش خالیه و Nginx تو این منطقه نمی شمرتش. پس رد کردنش با لایه اعتبارسنجی خودته.

IP مجاز، یه لایه اضافه که می ارزه

برای کلیدهایی که فقط از یه سرور مشخص استفاده می شن، می تونی IP مجاز رو هم ثبت کنی. بعضی سرویس دهنده های ایرانی خودشون همین رو می خوان. مثلاً تو اتصال به درگاه های پرداخت، گاهی مشکل اینه که IP سرور پذیرنده تو پنل ثبت نشده. تو این حالت کد مشکلی نداره و فقط باید IP ثبت بشه. پس اگه سرویس دهنده IP می خواد، قبل از دیباگ کد این رو چک کن. سرور خودت هم اگه قراره فقط از IP های مشخصی صدا زده بشه، همین محدودیت رو روی فایروال بذار. راهنمای تنظیم فایروال UFW روی سرور اوبونتو قاعده های پایه اش رو توضیح داده.

JWT بدون دردسر

JWT سه بخش داره: header، payload و امضا. محتوای payload رو کم و ضروری نگه دار:

{
  "sub": "user_1842",
  "role": "customer",
  "iat": 1735000000,
  "exp": 1735000900
}

exp زمان انقضاست. نمونه بالا ۱۵ دقیقه عمر داره. عمر کوتاه باعث می شه توکن دزدیده شده زود بی ارزش بشه. توکن رو تو هدر می فرستی:

curl -H "Authorization: Bearer <access_token>" https://api.example.ir/v1/profile

چند قاعده که نباید ازشون بگذری:

  1. الگوریتم رو سمت سرور ثابت کن. هیچ وقت اجازه نده توکن خودش بگه با چه الگوریتمی امضا شده. حمله هایی با alg: none سابقه دارن.
  2. الگوریتم رو با معماری هماهنگ انتخاب کن. برای سیستم تک سرویسی، HS256 با یه راز قوی کافیه. اگه چند سرویس باید توکن رو بررسی کنن ولی نباید بتونن بسازنش، RS256 با کلید عمومی و خصوصی بهتره.
  3. اطلاعات حساس تو payload نذار. شماره کارت، رمز و از این جور چیزها اصلاً جاشون اونجا نیست، چون هرکسی می تونه بخونه.
  4. انقضا رو همیشه چک کن. کتابخونه ها معمولاً خودشون چک می کنن، ولی تنظیمش رو یه بار مرور کن.
  5. راز امضا رو مثل رمز پایگاه داده نگه دار. نه تو ریپازیتوری؛ تو متغیر محیطی یا مخزن اسرار.

refresh token و ابطال

access token رو کوتاه نگه دار و refresh token رو با عمر بلندتر بساز، ولی سمت سرور هم ذخیره اش کن. وقتی کاربر خروج می کنه یا حسابش مشکوک می شه، refresh token رو پاک می کنی و دیگه نمی تونه access token جدید بگیره. توکن فعلی هم حداکثر تا چند دقیقه دیگه خودش منقضی می شه. سیستم های زیادی همین معامله رو قبول می کنن.

اگه API ات رو از صفر می نویسی و نمی خوای همه این تصمیم ها رو تنها بگیری، تیم ما تو خدمت طراحی و توسعه API این انتخاب ها رو با توجه به نیاز پروژه ات باهات مشخص می کنه.

اشتباه هایی که زیاد پیش میاد

کلید تو کد فرانت اند. اگه مرورگر باید با یه سرویس شخص ثالث حرف بزنه، درخواست رو از سرور خودت رد کن. سرور کلید رو اضافه می کنه و کاربر هیچ وقت نمی بینتش.

عمر طولانی برای JWT. «کاربر مدام لاگین نکنه» دلیل خوبی نیست. برای همین refresh token هست.

لاگ گرفتن از هدرها. اگه لاگ سرور یا ابزار مانیتورینگ کل هدرها رو ذخیره کنه، کلید و توکن هم تو لاگ می افتن. فیلدهای Authorization و X-API-Key رو ماسک کن.

یه کلید برای همه. اگه چند مشتری یا چند سرویس یه کلید مشترک داشته باشن، موقع نشت نمی دونی از کجا بوده و ابطالش همه رو قطع می کنه. برای هر مصرف کننده یه کلید جدا بساز.

نبود HTTPS. بدون TLS هر دو روش بی معنین. کلید و توکن تو هدر به صورت متن ساده سفر می کنن. گواهی SSL باید روی دامنه API هم فعال باشه.

شرایط شبکه ایران. اگه سرویس ورود یا کلیدهات رو روی سروری خارج از کشور گذاشتی و کاربر ایرانی باید بهش وصل بشه، با محدودیت اینترنت بین الملل ممکنه ورود کند بشه یا قطع بشه. سرویس ورود رو نزدیک کاربر بذار. مقاله محدودیت اینترنت بین الملل؛ سایت ایرانی خودت را کجا محافظت کنی درباره همین انتخاب مکان توضیح داده.

نداشتن برنامه چرخش کلید. از روز اول برای عوض کردن کلید برنامه داشته باش. اگه مشتری بتونه کلید جدید بسازه و قدیمی رو بعد از چند روز غیرفعال کنه، بدون قطعی می شه کلید رو عوض کرد.

سوالات متداول

آیا می شه فقط از کلید API برای اپلیکیشن موبایل استفاده کرد؟

برای شناسایی خود برنامه آره، ولی برای شناسایی کاربر کافی نیست. کلیدی که داخل اپ باشه با مهندسی معکوس درمیاد. اگه هر کاربر داده شخصی داره، کنارش توکن کاربر هم لازمه.

JWT از کلید API امن تره؟

نه به طور مطلق. JWT کوتاه عمر پنجره سوءاستفاده رو کم می کنه، ولی ابطال فوریش سخته. کلید API راحت تر ابطال می شه، ولی عمرش طولانیه. امنیت هر دو بیشتر به ذخیره سازی، HTTPS و مدیریت درست بستگی داره تا به خود روش.

JWT رو کجا نگه دارم، تو localStorage یا کوکی؟

برای وب معمولاً کوکی با HttpOnly و Secure امن تره، چون جاوااسکریپت صفحه بهش دسترسی نداره. localStorage با یه حفره XSS مستقیم لو می ره. اگه کوکی استفاده می کنی، به محافظت در برابر CSRF هم فکر کن.

اگه کلید API لو رفت اول چی کار کنم؟

اول کلید رو باطل کن و کلید جدید بساز. بعد لاگ ها رو بررسی کن تا ببینی از کی و از کدوم IP استفاده شده. اگه کلید به سرویس بیرونی مثل پنل پیامک یا درگاه وصل بوده، همون جا هم رمز یا کلید رو عوض کن.

برای یه سایت کوچک با افزونه و پنل پیامک کدوم رو انتخاب کنم؟

کلید API. ساده تره و نگهداری کمتری می خواد. فقط کلید رو رمزنگاری شده تو تنظیمات نگه دار و هیچ وقت تو صفحه نشونش نده.

از کجا شروع کنی؟

اول از خودت بپرس: مصرف کننده یه برنامه است یا یه آدم؟ اگه برنامه است، کلید API با ذخیره هش، سقف درخواست و امکان چرخش کافیه. اگه آدمه، ورود، JWT کوتاه عمر و refresh token لازمه. اگه هر دو هست، هر کدوم رو سر جای خودش بذار و مرزشون رو دقیق نگه دار.

بعدش این چک لیست کوچیک رو یه بار رد کن: HTTPS روی دامنه API فعال باشه، هدرهای حساس تو لاگ ماسک بشن، هر مصرف کننده کلید جدا داشته باشه، access token کوتاه عمر باشه و راز امضا بیرون از کد نگه داری بشه. اگه سرور خودت رو مدیریت می کنی، اشتباهات رایج در امن سازی SSH هم یه مرور خوب قبل از بالا آوردن API روی اینترنته.

  • احراز هویت API
  • کلید API
  • JWT
  • امنیت API
  • توسعه دهندگان

مقاله‌های مرتبط

ادامه همین موضوع در وبلاگ.

همه مقاله‌ها
کمک فنی

برای اجرای این کار کمک می‌خواهید؟

تیم فنی Wbweb از طراحی سایت تا هاست و سرور کنار شماست؛ درخواستتان را ثبت کنید یا تیکت بزنید.