در حال بارگذاری تصویر...

تصویر مقاله دسترسی به API لپ‌تاپ شما بدون نیاز به سرور

دسترسی به API لپ‌تاپ شما بدون نیاز به سرور

خلاصه:

در این آموزش یاد می‌گیریم چگونه با ngrok یک API جنگو که روی لپ‌تاپ و localhost اجرا می‌شود را بدون خرید سرور، از طریق اینترنت در دسترس دیگران قرار دهیم.

مقاله آموزشیلحظاتی پیش34 دقیقه0 نظر
۱۱ بازدید

فرض کنید یک API با Django ساخته‌اید و همه‌چیز هم به‌درستی کار می‌کند. با اجرای دستور زیر پروژه بالا می‌آید:

Bash / Shell
python manage.py runserver

و API شما مثلاً روی این آدرس در دسترس است:

Plain text
http://127.0.0.1:8000/api/hello/

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

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

اینجاست که ngrok به کارمان می‌آید.

با ngrok می‌توانیم سرویسی که روی localhost لپ‌تاپ اجرا شده را از طریق یک آدرس عمومی HTTPS روی اینترنت در دسترس قرار دهیم. ngrok برای این کار یک Endpoint عمومی ایجاد می‌کند و درخواست‌ها را از طریق یک اتصال امن به سرویس محلی ما Forward می‌کند.

در این مقاله این کار را مرحله‌به‌مرحله با Django انجام می‌دهیم.

نکته مهم: ngrok جایگزین سرور Production نیست. هدف اصلی این آموزش، تست، توسعه، دمو، Webhook و دسترسی موقت به پروژه‌ای است که روی سیستم خودمان اجرا می‌شود. خود Django نیز صراحتاً اعلام می‌کند که runserver یک Development Server است و برای محیط Production مناسب نیست.

ngrok دقیقاً چه کاری انجام می‌دهد؟

قبل از نصب ngrok بهتر است مکانیزم آن را خیلی ساده درک کنیم.

زمانی که Django را با دستور زیر اجرا می‌کنیم:

Bash / Shell
python manage.py runserver

به‌صورت پیش‌فرض سرور توسعه Django روی این آدرس اجرا می‌شود:

Plain text
127.0.0.1:8000

این آدرس متعلق به کامپیوتر خودمان است.

حالا ngrok را اجرا می‌کنیم و به آن می‌گوییم:

هر درخواستی که از اینترنت دریافت کردی، به پورت 8000 کامپیوتر من بفرست.

برای این کار کافی است بعداً دستور زیر را اجرا کنیم:

Bash / Shell
ngrok http 8000

ngrok یک URL عمومی شبیه این به ما می‌دهد:

Plain text
https://your-name.ngrok-free.app

در نتیجه اگر شخص دیگری این آدرس را باز کند:

Plain text
https://your-name.ngrok-free.app/api/hello/

درخواست تقریباً این مسیر را طی می‌کند:

Plain text
کاربر اینترنت
     ↓
آدرس HTTPS مربوط به ngrok
     ↓
تونل ngrok
     ↓
localhost:8000
     ↓
Django
     ↓
API ما

یعنی Django همچنان روی لپ‌تاپ خودمان اجرا می‌شود؛ ngrok فقط یک مسیر عمومی برای رسیدن درخواست‌های اینترنت به آن ایجاد کرده است.

در حال بارگذاری تصویر...

یک دیاگرام آموزشی افقی و ساده با پس‌زمینه روشن و تم لایت و تم لایت طراحی کن. در سمت چپ چند دستگاه شامل موبایل و لپ‌تاپ با عنوان فارسی «کاربر اینترنت» قرار داشته باشند. یک فلش به یک ابر در مرکز با عنوان «آدرس عمومی HTTPS در ngrok» برسد. سپس یک تونل گرافیکی با عنوان «تونل امن ngrok» به یک لپ‌تاپ در سمت راست متصل شود. داخل لپ‌تاپ عبارت «Django API» و زیر آن «localhost:8000» نمایش داده شود. مسیر با فلش‌های واضح نشان داده شود: «کاربر اینترنت ← ngrok ← لپ‌تاپ شما». هدف تصویر توضیح معماری دسترسی به localhost از اینترنت باشد، نه تزئین. تمام نوشته‌ها فارسی باشند به‌جز Django، ngrok و localhost. رنگ‌های شاد و پس‌زمینه روشن و تم لایت. در پایین سمت چپ عبارت «codingyar.com» و پایین سمت راست عبارت «وبسایت آموزش برنامه نویسی کدینگ‌یار» قرار بگیرد.

ساخت یک API ساده در Django

اگر در حال حاضر یک پروژه Django دارید و چند URL روی localhost شما کار می‌کنند، این بخش را رد کنید. مهم نیست API شما با Django REST Framework نوشته شده، JsonResponse استفاده کرده‌اید یا حتی یک پروژه بزرگ دارید.

تنها چیزی که برای ادامه نیاز داریم این است که یک آدرس مثل این روی لپ‌تاپ شما کار کند:

Plain text
http://127.0.0.1:8000/api/...

اما برای اینکه آموزش قابل اجرا باشد، یک API بسیار ساده هم می‌سازیم.

فرض می‌کنیم از قبل یک پروژه Django دارید. یک App به نام api می‌سازیم:

Bash / Shell
python manage.py startapp api

سپس آن را در settings.py اضافه کنید:

Python
INSTALLED_APPS = [
    # ...
    "api",
]

در فایل api/views.py یک View ساده می‌نویسیم:

Python
from django.http import JsonResponse
from django.views.decorators.http import require_GET


@require_GET
def hello(request):
    return JsonResponse({
        "message": "Hello from my laptop!",
        "status": "ok",
    })

حالا فایل api/urls.py را ایجاد کنید:

Python
from django.urls import path

from .views import hello


urlpatterns = [
    path("hello/", hello, name="hello"),
]

و در فایل اصلی urls.py پروژه، URLهای این App را اضافه کنید:

Python
from django.contrib import admin
from django.urls import include, path


urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/", include("api.urls")),
]

پروژه را اجرا کنید:

Bash / Shell
python manage.py runserver

حالا باید بتوانید آدرس زیر را باز کنید:

Plain text
http://127.0.0.1:8000/api/hello/

و خروجی تقریباً چنین چیزی باشد:

JSON
{
    "message": "Hello from my laptop!",
    "status": "ok"
}

تا اینجا هیچ ارتباطی با ngrok نداریم. API ما فقط به‌صورت Local اجرا شده است.

نصب ngrok

روش نصب ngrok در سیستم‌عامل‌های مختلف کمی متفاوت است. ابتدا ویندوز را بررسی می‌کنیم و سپس سراغ macOS و Linux می‌رویم.

این آموزش بر اساس روش نصب و CLI فعلی ngrok در زمان نگارش مقاله نوشته شده است. خود ngrok برای Windows استفاده از Microsoft Store را به‌عنوان یکی از روش‌های اصلی نصب ارائه می‌کند، برای macOS نصب با Homebrew و برای Linux نیز بسته‌های رسمی از جمله Apt در دسترس هستند.

نصب ngrok در ویندوز

برای ویندوز ساده‌ترین روش این است که وارد صفحه رسمی دانلود ngrok شوید و نسخه Windows را نصب کنید.

ngrok در حال حاضر روش نصب از طریق Microsoft Store را نیز ارائه می‌کند و در مستندات رسمی آن را گزینه امن پیشنهادی برای Windows معرفی کرده است.

بعد از نصب، PowerShell، Command Prompt یا Windows Terminal را باز کنید و دستور زیر را اجرا کنید:

Bash / Shell
ngrok version

اگر نسخه ngrok نمایش داده شد، نصب موفق بوده است.

مثلاً خروجی ساختاری شبیه این خواهد داشت:

Plain text
ngrok version 3.x.x

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

اگر ngrok را به‌صورت فایل مستقل نصب کرده‌اید و نه از Package Manager، می‌توانید برای بررسی و نصب نسخه Stable جدید از این دستور استفاده کنید:

Bash / Shell
ngrok update

مستندات ngrok توصیه می‌کنند در صورتی که برنامه را با Package Manager نصب کرده‌اید، به‌جای ngrok update از همان Package Manager برای آپدیت استفاده کنید.

اگر دستور ngrok شناخته نشد

اگر با چنین خطایی مواجه شدید:

Plain text
'ngrok' is not recognized...

یا:

Plain text
ngrok: command not found

احتمالاً فایل اجرایی ngrok داخل PATH سیستم قرار نگرفته است.

اگر نسخه مستقل ngrok.exe را دانلود کرده‌اید، می‌توانید آن را در پوشه‌ای مثل:

Plain text
C:\Tools\ngrok\

قرار دهید و این پوشه را به Environment Variable مربوط به PATH ویندوز اضافه کنید.

بعد از تغییر PATH، Terminal را ببندید و دوباره باز کنید.

نصب ngrok در macOS

اگر Homebrew روی سیستم نصب است، نصب ngrok بسیار ساده است:

Bash / Shell
brew install ngrok

این همان روش نصب ارائه‌شده در مستندات رسمی ngrok برای macOS است.

بعد از نصب:

Bash / Shell
ngrok version

برای آپدیت نسخه‌ای که با Homebrew نصب شده نیز از Homebrew استفاده کنید:

Bash / Shell
brew upgrade ngrok

نصب ngrok در Linux

ngrok برای Linux روش‌های مختلفی مثل Apt، Snap و دانلود مستقیم ارائه می‌کند.

اگر توزیع شما مبتنی بر Debian یا Ubuntu است، می‌توانید از Repository رسمی ngrok استفاده کنید:

Bash / Shell
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \
&& echo "deb https://ngrok-agent.s3.amazonaws.com bookworm main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list \
&& sudo apt update \
&& sudo apt install ngrok

این دستور مطابق روش Apt ارائه‌شده در مستندات رسمی ngrok است.

بعد از نصب:

Bash / Shell
ngrok version

ساخت حساب ngrok و دریافت Authtoken

بعد از نصب باید ngrok را به حساب خود متصل کنیم.

یک حساب در ngrok ایجاد کنید و سپس در Dashboard وارد بخش مربوط به Authtoken شوید.

توکنی شبیه این دریافت خواهید کرد:

Plain text
2abcDEFxxxxxxxxxxxxxxxxxxxx

حالا در Terminal دستور زیر را اجرا کنید:

Bash / Shell
ngrok config add-authtoken YOUR_AUTHTOKEN

برای مثال:

Bash / Shell
ngrok config add-authtoken 2abcDEFxxxxxxxxxxxxxxxxxxxx

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

این دستور Authtoken را در فایل تنظیمات ngrok ذخیره می‌کند. ngrok برای احراز هویت Agent از Authtoken استفاده می‌کند.

Authtoken یک اطلاعات محرمانه است.

آن را داخل GitHub، فایل‌های پروژه، اسکرین‌شات عمومی یا مقاله قرار ندهید.

آنلاین کردن Django با ngrok

حالا به قسمت اصلی آموزش رسیدیم.

در Terminal اول Django را اجرا کنید:

Bash / Shell
python manage.py runserver 8000

مطمئن شوید آدرس Local شما کار می‌کند:

Plain text
http://127.0.0.1:8000/api/hello/

حالا یک Terminal جدید باز کنید.

Django باید همچنان در Terminal اول در حال اجرا باشد.

در Terminal دوم بنویسید:

Bash / Shell
ngrok http 8000

معنای این دستور خیلی ساده است:

برای سرویس HTTP که روی پورت 8000 سیستم من اجرا شده، یک Endpoint عمومی ایجاد کن.

ngrok نیز در مستندات CLI خود دقیقاً از همین ساختار ngrok http PORT برای Forward کردن یک سرویس HTTP محلی استفاده می‌کند.

بعد از اجرای دستور، آدرسی شبیه این مشاهده خواهید کرد:

Plain text
https://your-assigned-name.ngrok-free.app

در پلن رایگان فعلی ngrok یک Development Domain اختصاص‌یافته به حساب در اختیار کاربر قرار می‌گیرد. جزئیات محدودیت‌های پلن ممکن است در آینده تغییر کند.

حالا اگر API ما این بود:

Plain text
http://127.0.0.1:8000/api/hello/

نسخه عمومی آن می‌شود:

Plain text
https://your-assigned-name.ngrok-free.app/api/hello/

اما احتمال زیادی وجود دارد که در اولین درخواست با یک خطای Django مواجه شوید.

حل خطای DisallowedHost در Django

فرض کنید URL عمومی ngrok شما این باشد:

Plain text
https://codingyar-demo.ngrok-free.app

اگر آن را باز کنید ممکن است Django این خطا را نمایش دهد:

Plain text
DisallowedHost
Invalid HTTP_HOST header

علت این خطا ngrok نیست.

Django درخواست را دریافت کرده، اما Domain جدید را نمی‌شناسد.

Django برای محافظت در برابر حملات مرتبط با Host header، مقدار Host درخواست را با تنظیم ALLOWED_HOSTS مقایسه می‌کند.

بنابراین وارد settings.py شوید و Domain مربوط به ngrok را اضافه کنید:

Python
ALLOWED_HOSTS = [
    "127.0.0.1",
    "localhost",
    "codingyar-demo.ngrok-free.app",
]

دقت کنید که داخل ALLOWED_HOSTS فقط نام Host را قرار می‌دهیم.

اشتباه:

Python
ALLOWED_HOSTS = [
    "https://codingyar-demo.ngrok-free.app",
]

درست:

Python
ALLOWED_HOSTS = [
    "codingyar-demo.ngrok-free.app",
]

حالا Django را Restart کنید:

Bash / Shell
python manage.py runserver 8000

و دوباره API را از URL عمومی باز کنید:

Plain text
https://codingyar-demo.ngrok-free.app/api/hello/

این بار باید همان JSON مربوط به لپ‌تاپ خودتان را دریافت کنید:

JSON
{
    "message": "Hello from my laptop!",
    "status": "ok"
}

تبریک! در این لحظه API که روی لپ‌تاپ شما اجرا شده، از اینترنت قابل دسترسی است.

اگر این لینک را برای شخص دیگری بفرستید، تا زمانی که لپ‌تاپ شما روشن باشد و Django و ngrok در حال اجرا باشند، او نیز می‌تواند API را فراخوانی کند.

آیا می‌توانیم .ngrok-free.app را کامل داخل ALLOWED_HOSTS قرار دهیم؟

Django اجازه می‌دهد Hostهایی که با یک نقطه شروع می‌شوند تمام Subdomainهای آن دامنه را Match کنند. بنابراین از نظر فنی می‌توان تنظیمی شبیه این داشت:

Python
ALLOWED_HOSTS = [
    "127.0.0.1",
    "localhost",
    ".ngrok-free.app",
]

اما در حالت عادی اضافه کردن Domain دقیق خودتان انتخاب بهتری است:

Python
ALLOWED_HOSTS = [
    "127.0.0.1",
    "localhost",
    "codingyar-demo.ngrok-free.app",
]

هرچه ALLOWED_HOSTS محدودتر باشد، رفتار پروژه قابل‌کنترل‌تر است.

از این تنظیم هم برای راحتی استفاده نکنید:

Python
ALLOWED_HOSTS = ["*"]

خصوصاً زمانی که برنامه را واقعاً روی اینترنت قرار داده‌اید.

هدف ALLOWED_HOSTS یک کنترل امنیتی واقعی در Django است، نه خطایی که لازم باشد به هر روشی از شر آن خلاص شویم.

تست API عمومی با curl

تا اینجا API را احتمالاً با مرورگر تست کرده‌ایم.

اما برای اینکه مطمئن شویم واقعاً از طریق اینترنت قابل فراخوانی است، می‌توانیم curl استفاده کنیم.

Bash / Shell
curl https://codingyar-demo.ngrok-free.app/api/hello/

در Windows اگر PowerShell شما curl را به Command دیگری Alias کرده است، می‌توانید بنویسید:

Bash / Shell
curl.exe https://codingyar-demo.ngrok-free.app/api/hello/

خروجی:

JSON
{"message":"Hello from my laptop!","status":"ok"}

حتی بهتر است آدرس را روی موبایل و با اینترنت سیم‌کارت امتحان کنید.

در این حالت دیگر موبایل روی شبکه Wi-Fi لپ‌تاپ نیست و مطمئن می‌شوید درخواست واقعاً از اینترنت به پروژه شما رسیده است.

در حال بارگذاری تصویر...

یک تصویر آموزشی دو بخشی با پس‌زمینه روشن و تم لایت و تم لایت طراحی کن. سمت چپ یک لپ‌تاپ ویندوزی نمایش داده شود که دو پنجره Terminal باز دارد: در Terminal اول عبارت «Django روی پورت ۸۰۰۰» و در Terminal دوم عبارت «ngrok http 8000». در بالای آن یک آدرس عمومی مثل «https://example.ngrok-free.app» دیده شود. سمت راست یک موبایل با اینترنت سیم‌کارت قرار داشته باشد که خروجی JSON شامل «پیام: API در دسترس است» را نشان می‌دهد. یک فلش از موبایل به اینترنت، از اینترنت به ngrok و از ngrok به لپ‌تاپ کشیده شود. هدف تصویر نشان دادن این باشد که موبایل خارج از شبکه محلی به API روی لپ‌تاپ دسترسی دارد. تمام نوشته‌های توضیحی فارسی باشند. رنگ‌های شاد. در پایین سمت چپ «codingyar.com» و در پایین سمت راست «وبسایت آموزش برنامه نویسی کدینگ‌یار» درج شود.

آیا برای هر URL باید یک ngrok جدا اجرا کنیم؟

خیر.

فرض کنید پروژه Django شما این Endpointها را دارد:

Plain text
/api/users/
/api/products/
/api/orders/
/api/login/

همه آن‌ها روی یک سرور Django و پورت 8000 اجرا می‌شوند:

Plain text
http://localhost:8000

کافی است فقط یک بار اجرا کنید:

Bash / Shell
ngrok http 8000

اگر Domain عمومی شما این باشد:

Plain text
https://codingyar-demo.ngrok-free.app

تمام Endpointها به شکل زیر قابل دسترسی می‌شوند:

Plain text
https://codingyar-demo.ngrok-free.app/api/users/
https://codingyar-demo.ngrok-free.app/api/products/
https://codingyar-demo.ngrok-free.app/api/orders/
https://codingyar-demo.ngrok-free.app/api/login/

ngrok کل سرویس روی آن پورت را Public می‌کند، نه فقط یک URL خاص را.

اگر Django روی پورت دیگری اجرا شود چه؟

هیچ مشکلی نیست.

مثلاً:

Bash / Shell
python manage.py runserver 9000

در این حالت Django روی پورت 9000 است، پس ngrok را نیز برای همان پورت اجرا می‌کنیم:

Bash / Shell
ngrok http 9000

یا اگر برنامه دیگری روی پورت 3000 دارید:

Bash / Shell
ngrok http 3000

قاعده کلی این است:

Bash / Shell
ngrok http PORT

Port باید همان پورتی باشد که سرویس Local شما روی آن Listen می‌کند.

HTTPS از کجا آمد؟

نکته جالب این است که Django روی لپ‌تاپ ما معمولاً با HTTP اجرا شده:

Plain text
http://localhost:8000

ولی URL عمومی ngrok می‌تواند HTTPS باشد:

Plain text
https://codingyar-demo.ngrok-free.app

ngrok اتصال عمومی HTTPS را مدیریت کرده و سپس Traffic را از طریق تونل خود به سرویس Local Forward می‌کند. HTTPS Endpoint و Automatic Certificates از قابلیت‌های ngrok هستند.

بنابراین برای یک تست ساده لازم نیست روی Django Development Server خودتان SSL Certificate نصب کنید.

تفاوت ALLOWED_HOSTS، CORS و CSRF

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

ALLOWED_HOSTS

ALLOWED_HOSTS مشخص می‌کند Django اجازه دارد درخواست‌هایی با چه Hostهایی را قبول کند.

وقتی ngrok برای ما Domain جدید ایجاد می‌کند:

Plain text
codingyar-demo.ngrok-free.app

باید آن Domain را به Django معرفی کنیم:

Python
ALLOWED_HOSTS = [
    "localhost",
    "127.0.0.1",
    "codingyar-demo.ngrok-free.app",
]

اگر این کار را انجام ندهیم معمولاً DisallowedHost می‌گیریم.

CORS

CORS داستان متفاوتی دارد.

فرض کنید Frontend شما روی این آدرس اجرا شده:

Plain text
https://frontend.example.com

و JavaScript داخل مرورگر می‌خواهد به API شما درخواست بزند:

Plain text
https://codingyar-demo.ngrok-free.app/api/products/

این دو Origin متفاوت دارند.

در چنین حالتی مرورگر قوانین CORS را اعمال می‌کند.

ngrok مانع CORS نیست؛ برنامه شما باید Headerهای مناسب CORS را برگرداند. خود مستندات ngrok نیز تأکید می‌کنند که Application باید CORS headers مناسب را ارائه کند.

اگر API را از Postman، curl یا یک Backend دیگر صدا بزنید، محدودیت CORS مرورگر را ندارید.

تنظیم CORS در Django

یکی از ابزارهای رایج برای این کار django-cors-headers است:

Bash / Shell
python -m pip install django-cors-headers

سپس:

Python
INSTALLED_APPS = [
    # ...
    "corsheaders",
]

Middleware را نیز اضافه کنید:

Python
MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    # ...
]

و Origin واقعی Frontend را مجاز کنید:

Python
CORS_ALLOWED_ORIGINS = [
    "https://frontend.example.com",
]

برای Development ممکن است نمونه‌هایی مثل این ببینید:

Python
CORS_ALLOW_ALL_ORIGINS = True

اما این تنظیم را بدون دلیل روی یک API عمومی رها نکنید.

در زمان نگارش این مقاله، نسخه 4.9.0 پکیج django-cors-headers در PyPI به‌عنوان آخرین Release ثبت شده و پشتیبانی رسمی آن در Metadata تا Django 6.0 اعلام شده است؛ اگر از نسخه جدیدتری از Django استفاده می‌کنید، Compatibility نسخه فعلی پکیج را قبل از نصب بررسی کنید.

CSRF_TRUSTED_ORIGINS

CSRF_TRUSTED_ORIGINS هم با ALLOWED_HOSTS یکی نیست.

Django برای درخواست‌های Unsafe مثل:

Plain text
POST
PUT
PATCH
DELETE

در سناریوهایی که CSRF Protection فعال است، Origin درخواست را بررسی می‌کند. طبق مستندات Django، اگر درخواست Origin داشته باشد، Origin باید با Host مورد انتظار تطابق داشته باشد یا در فهرست Trusted Origins قرار گرفته باشد.

اگر هم Frontend و هم API از همان ngrok URL استفاده کنند، معمولاً نیازی نیست صرفاً به‌دلیل استفاده از ngrok چیزی به CSRF_TRUSTED_ORIGINS اضافه کنید.

اما فرض کنید Frontend روی این Origin است:

Plain text
https://frontend.example.com

و با Cookie یا Session به Django درخواست POST ارسال می‌کند.

در صورت نیاز می‌توانید همان Origin فرستنده درخواست را Trust کنید:

Python
CSRF_TRUSTED_ORIGINS = [
    "https://frontend.example.com",
]

نکته مهم همین است:

CSRF_TRUSTED_ORIGINS را کورکورانه با تمام دامنه‌های ngrok پر نکنید. ابتدا ببینید Origin واقعی درخواست چیست و چرا Django آن را Reject کرده است.

یک تنظیم پیشنهادی برای settings.py

برای یک پروژه آزمایشی که فقط قرار است با ngrok تست شود، تنظیمات می‌تواند چیزی شبیه این باشد:

Python
ALLOWED_HOSTS = [
    "localhost",
    "127.0.0.1",
    "codingyar-demo.ngrok-free.app",
]

اگر Frontend جداگانه‌ای دارید:

Python
CORS_ALLOWED_ORIGINS = [
    "https://frontend.example.com",
]

و اگر Session/CSRF در درخواست Cross-Origin مطرح باشد:

Python
CSRF_TRUSTED_ORIGINS = [
    "https://frontend.example.com",
]

این سه تنظیم سه مسئله متفاوت را حل می‌کنند.

مشاهده درخواست‌هایی که از ngrok عبور می‌کنند

یکی از امکانات بسیار کاربردی ngrok این است که می‌توانید Requestهایی که به API شما می‌رسند را Inspect کنید.

Traffic Inspector به شما کمک می‌کند مواردی مثل موارد زیر را بررسی کنید:

  • Method درخواست
  • URL
  • Headerها
  • Status Code
  • مدت زمان پاسخ
  • Request و Response در حالت Capture مناسب
  • Replay کردن Request در شرایط پشتیبانی‌شده

ngrok یک Traffic Inspector در Dashboard دارد و Agent مستقل نیز معمولاً رابط Local Inspection را روی آدرس زیر ارائه می‌کند:

Plain text
http://localhost:4040

مستندات فعلی ngrok، Traffic Inspector ابری Dashboard را نیز برای بررسی و Replay ترافیک ارائه می‌کنند.

این قابلیت مخصوصاً هنگام تست Webhookها فوق‌العاده مفید است.

مثلاً سرویس خارجی یک درخواست POST برای لپ‌تاپ شما ارسال می‌کند، اما Django خطای 400 یا 500 می‌دهد.

به‌جای حدس زدن می‌توانید درخواست ورودی را Inspect کنید.

نکته امنیتی درباره Traffic Inspector

اگر Full Capture را فعال کنید، Body و Headerهای Request و Response ممکن است در Traffic Inspector ذخیره شوند.

پس در زمان کار با اطلاعات حساسی مثل Password، Token، اطلاعات شخصی یا داده واقعی کاربران، تنظیمات Capture را با دقت بررسی کنید. مستندات ngrok نیز درباره ذخیره داده‌های حساس در Full Capture هشدار می‌دهند.

یک کاربرد واقعی: تست Webhook روی لپ‌تاپ

یکی از بهترین کاربردهای ngrok تست Webhook است.

فرض کنید یک درگاه پرداخت یا سرویس خارجی بعد از انجام عملیات باید درخواست زیر را ارسال کند:

Plain text
POST /api/payment/callback/

سرویس خارجی نمی‌تواند به این آدرس دسترسی داشته باشد:

Plain text
http://127.0.0.1:8000/api/payment/callback/

چون 127.0.0.1 برای خود لپ‌تاپ شماست.

ngrok را اجرا می‌کنیم:

Bash / Shell
ngrok http 8000

و آدرس عمومی می‌گیریم:

Plain text
https://codingyar-demo.ngrok-free.app

حالا Callback URL را در سرویس خارجی می‌گذاریم:

Plain text
https://codingyar-demo.ngrok-free.app/api/payment/callback/

درخواست سرویس خارجی وارد ngrok می‌شود و در نهایت به Django روی لپ‌تاپ شما می‌رسد.

بدون خرید VPS، تنظیم Nginx، گرفتن Domain یا Deploy کردن پروژه می‌توانیم Webhook واقعی را تست کنیم.

یک کاربرد دیگر: اتصال برنامه موبایل به Django لپ‌تاپ

فرض کنید شما Backend پروژه را با Django نوشته‌اید و یکی از اعضای تیم در حال ساخت اپلیکیشن Android یا iOS است.

Backend روی سیستم شما اجرا شده:

Plain text
http://localhost:8000

برنامه موبایل هم طبیعتاً نمی‌تواند از اینترنت به localhost کامپیوتر شما دسترسی داشته باشد.

با ngrok:

Bash / Shell
ngrok http 8000

می‌توانید Base URL موقت API را در اختیار برنامه‌نویس موبایل قرار دهید:

Plain text
https://codingyar-demo.ngrok-free.app/api/

حالا اپ موبایل می‌تواند Endpointهای واقعی Django لپ‌تاپ شما را فراخوانی کند.

برای پروژه‌های تیمی کوچک و تست سریع، این روش بسیار کاربردی است.

آیا ngrok باعث می‌شود لپ‌تاپ ما سرور شود؟

از یک نظر، برنامه روی لپ‌تاپ شما در حال پاسخ دادن به درخواست‌های اینترنت است.

اما نباید نتیجه بگیریم که حالا دیگر نیازی به Deployment نداریم.

تا زمانی که این موارد برقرار باشند API کار می‌کند:

Plain text
لپ‌تاپ روشن باشد
+
اتصال اینترنت برقرار باشد
+
Django اجرا باشد
+
ngrok اجرا باشد

اگر یکی از آن‌ها قطع شود، API دیگر در دسترس نیست.

بنابراین ngrok برای مواردی مثل این عالی است:

  • تست API
  • دمو به مشتری یا همکار
  • تست Webhook
  • توسعه Frontend و Backend به‌صورت جداگانه
  • اتصال موقت اپ موبایل
  • تست سرویس‌های خارجی
  • Debug کردن Callbackها
  • نمایش سریع یک نمونه اولیه

اما برای سرویس Production با کاربران واقعی، همچنان باید از معماری Deployment مناسب استفاده کنید.

نکات امنیتی بسیار مهم

زمانی که دستور زیر را اجرا می‌کنید:

Bash / Shell
ngrok http 8000

دیگر نباید با پروژه مثل یک localhost خصوصی رفتار کنید.

شما یک مسیر عمومی از اینترنت به برنامه ساخته‌اید.

۱. API بدون احراز هویت را بی‌دلیل عمومی نکنید

اگر Endpoint حساسی دارید:

Plain text
/api/users/
/api/orders/
/api/admin-data/

صرفاً به این دلیل که URL ngrok را کسی نمی‌داند، نباید آن را امن فرض کنید.

Authentication و Authorization پروژه باید همچنان فعال باشند.

۲. DEBUG را جدی بگیرید

در Development معمولاً داریم:

Python
DEBUG = True

اگر Exception رخ دهد، Django ممکن است اطلاعات Debug زیادی نمایش دهد.

وقتی پروژه از طریق ngrok عمومی شده، این اطلاعات دیگر فقط روی لپ‌تاپ خودتان دیده نمی‌شوند.

برای Demo عمومی یا دسترسی افراد ناشناس، DEBUG=True انتخاب امنی نیست.

ضمن اینکه Django Development Server اساساً برای Production طراحی نشده است.

۳. Authtoken را منتشر نکنید

این دستور:

Bash / Shell
ngrok config add-authtoken YOUR_AUTHTOKEN

حاوی یک Credential مربوط به حساب ngrok شماست.

آن را در فایل پروژه ننویسید و Commit نکنید.

۴. اطلاعات واقعی کاربران را برای تست استفاده نکنید

اگر فقط در حال تست هستید، تا حد ممکن از اطلاعات Mock یا Test استفاده کنید.

Public کردن لپ‌تاپ توسعه نباید باعث شود دیتابیس حاوی اطلاعات حساس ناخواسته در معرض Endpointهای آزمایشی قرار بگیرد.

۵. بعد از پایان تست ngrok را ببندید

برای متوقف کردن آن کافی است در Terminal مربوط به ngrok:

Plain text
Ctrl + C

را بزنید.

وقتی دیگر به Endpoint عمومی نیاز ندارید، باز نگه داشتن آن فایده‌ای ندارد.

محدودیت پلن رایگان ngrok

ngrok پلن رایگان هم دارد و برای سناریوی این مقاله معمولاً همین پلن کافی است.

در وضعیت فعلی پلن Free، یک Development Domain اختصاص‌یافته، تا 3 Online Endpoint، سقف 20 هزار HTTP/S Request در ماه و 1 گیگابایت Data Transfer Out در نظر گرفته شده است. این اعداد متعلق به زمان نگارش مقاله هستند و ممکن است بعداً تغییر کنند.

برای تست API معمولاً مسئله‌ای ایجاد نمی‌شود، اما اگر قرار است ترافیک واقعی و مداوم داشته باشید، ngrok رایگان یا Development Server Django راه‌حل Production محسوب نمی‌شوند.

صفحه هشدار ngrok در مرورگر چیست؟

ممکن است در پلن رایگان هنگام باز کردن بعضی URLها در مرورگر با صفحه‌ای از سمت ngrok روبه‌رو شوید که قبل از ورود به سایت یک هشدار نمایش می‌دهد.

این Interstitial برای کاهش سوءاستفاده‌هایی مثل Phishing استفاده می‌شود.

طبق مستندات فعلی ngrok، این صفحه برای Browser Traffic مربوط به HTML اعمال می‌شود و روی APIهایی که به‌صورت Programmatic فراخوانی می‌شوند تأثیر مشابهی ندارد. همچنین کلاینت در صورت نیاز می‌تواند Header زیر را ارسال کند:

Plain text
ngrok-skip-browser-warning

با یک مقدار دلخواه.

بنابراین اگر هدف شما API و فراخوانی آن با fetch، Postman، curl یا برنامه موبایل باشد، رفتار با باز کردن مستقیم یک صفحه HTML در مرورگر می‌تواند متفاوت باشد.

خطاهای رایج ngrok و Django

خطای DisallowedHost

اگر دیدید:

Plain text
DisallowedHost
Invalid HTTP_HOST header

Domain مربوط به ngrok را در ALLOWED_HOSTS اضافه کنید:

Python
ALLOWED_HOSTS = [
    "localhost",
    "127.0.0.1",
    "codingyar-demo.ngrok-free.app",
]

ngrok باز می‌شود ولی API پاسخ نمی‌دهد

اول بررسی کنید Django هنوز در حال اجراست:

Bash / Shell
python manage.py runserver 8000

سپس Local URL را تست کنید:

Plain text
http://127.0.0.1:8000/api/hello/

اگر Local URL هم کار نمی‌کند، مشکل از ngrok نیست.

پورت اشتباه است

اگر Django روی 8080 اجرا شده:

Bash / Shell
python manage.py runserver 8080

نباید بنویسید:

Bash / Shell
ngrok http 8000

باید بنویسید:

Bash / Shell
ngrok http 8080

خطای CORS در مرورگر

اگر Console مرورگر چیزی درباره CORS می‌گوید، احتمالاً خود Tunnel سالم است.

باید CORS را در Application تنظیم کنید.

ngrok به‌تنهایی CORS Policy اپلیکیشن Django شما را حل نمی‌کند.

خطای CSRF Failed

اگر Requestهای POST یا سایر Requestهای Unsafe با خطای CSRF مواجه می‌شوند، موارد زیر را بررسی کنید:

  • Origin درخواست چیست؟
  • آیا از Session Authentication استفاده می‌کنید؟
  • Frontend روی Domain دیگری است؟
  • CSRF_TRUSTED_ORIGINS واقعاً برای آن Origin لازم است؟
  • CSRF Token ارسال می‌شود؟

مشکل CSRF را با csrf_exempt روی همه Viewها «حل» نکنید؛ ابتدا علت خطا را پیدا کنید.

دستور ngrok پیدا نمی‌شود

اگر:

Plain text
ngrok: command not found

دریافت کردید، نصب یا PATH را بررسی کنید.

با این دستور هم می‌توانید نصب را تست کنید:

Bash / Shell
ngrok version

ngrok به سرویس متصل نمی‌شود

خود ngrok دستور عیب‌یابی دارد:

Bash / Shell
ngrok diagnose

این Command برای بررسی مشکلات Connectivity Agent در CLI رسمی ngrok در دسترس است.

آیا لازم است Port Forwarding مودم انجام دهیم؟

خیر، و این یکی از دلایل جذاب بودن ngrok است.

در روش‌های سنتی ممکن بود نیاز باشد:

  • IP عمومی داشته باشید
  • NAT را بررسی کنید
  • Port Forwarding مودم انجام دهید
  • Firewall را تنظیم کنید
  • SSL Certificate بگیرید

اما Agent مربوط به ngrok از داخل سیستم شما یک اتصال خروجی امن به سرویس ngrok ایجاد می‌کند. مستندات ngrok اعلام می‌کنند اتصال Agent به سرویس ngrok از طریق پورت 443 برقرار می‌شود.

در نتیجه در سناریوی معمول این مقاله نیازی نیست پورت 8000 مودم خود را مستقیماً به اینترنت باز کنید.

کل فرایند در چند دستور

اگر پروژه Django شما از قبل آماده است، کل آموزش در عمل به چند مرحله خلاصه می‌شود.

ابتدا Django:

Bash / Shell
python manage.py runserver 8000

تست Local:

Plain text
http://127.0.0.1:8000/api/hello/

یک بار Authtoken را تنظیم کنید:

Bash / Shell
ngrok config add-authtoken YOUR_AUTHTOKEN

سپس:

Bash / Shell
ngrok http 8000

URL دریافت‌شده را در settings.py قرار دهید:

Python
ALLOWED_HOSTS = [
    "localhost",
    "127.0.0.1",
    "YOUR_DOMAIN.ngrok-free.app",
]

Django را Restart کنید و API عمومی را باز کنید:

Plain text
https://YOUR_DOMAIN.ngrok-free.app/api/hello/

همین.

جمع‌بندی

برای اینکه دیگران بتوانند به API روی لپ‌تاپ ما دسترسی داشته باشند، لزوماً لازم نیست همان لحظه پروژه را روی VPS یا یک سرویس Cloud Deploy کنیم.

اگر هدف تست، دمو یا توسعه است، ngrok می‌تواند بین اینترنت و localhost ما یک مسیر عمومی ایجاد کند.

در مثال این مقاله Django روی:

Plain text
http://localhost:8000

اجرا شد و با دستور:

Bash / Shell
ngrok http 8000

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

سپس با اضافه کردن Domain ngrok به:

Python
ALLOWED_HOSTS

توانستیم API را از خارج از کامپیوتر خودمان فراخوانی کنیم.

نکته‌ای که باید به خاطر بسپارید این است:

Plain text
ngrok = دسترسی موقت و سریع به سرویس Local

و نه:

Plain text
ngrok + runserver = Deployment واقعی Production

برای تست Webhook، اتصال اپ موبایل، همکاری Frontend و Backend، نمایش سریع پروژه و Debug کردن API، ngrok یکی از ابزارهایی است که می‌تواند مقدار زیادی از دردسرهای راه‌اندازی یک سرور موقت را حذف کند.

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

آیا ngrok رایگان است؟

بله، ngrok در حال حاضر پلن رایگان دارد که برای تست و Development قابل استفاده است، البته محدودیت‌هایی در تعداد Request، Data Transfer و Endpointها دارد.

آیا برای ngrok باید سرور بخریم؟

خیر. در سناریوی این مقاله برنامه روی لپ‌تاپ خودتان اجرا می‌شود و ngrok یک Endpoint عمومی برای دسترسی به آن ایجاد می‌کند.

آیا لپ‌تاپ باید روشن بماند؟

بله. چون خود Django روی لپ‌تاپ شما اجرا می‌شود، با خاموش شدن لپ‌تاپ یا توقف Django/ngrok، API هم از دسترس خارج می‌شود.

آیا می‌توان Django REST Framework را هم با ngrok آنلاین کرد؟

بله. برای ngrok تفاوت خاصی ندارد که API با JsonResponse نوشته شده باشد یا Django REST Framework. چیزی که اهمیت دارد آدرس و Port سرویس Local است.

مثلاً:

Bash / Shell
ngrok http 8000

آیا ngrok مشکل CORS را حل می‌کند؟

خیر. ngrok API را قابل دسترس می‌کند، ولی CORS مربوط به Browser و Headerهای پاسخ Application است. اگر Frontend روی Origin دیگری قرار دارد باید CORS را در Django یا لایه مناسب دیگری تنظیم کنید.

چرا Django خطای DisallowedHost می‌دهد؟

چون Domain ایجادشده توسط ngrok داخل ALLOWED_HOSTS پروژه نیست. Domain دقیق را به ALLOWED_HOSTS اضافه کنید.

آیا می‌توان از ngrok برای Production استفاده کرد؟

خود ngrok امکانات Production نیز ارائه می‌دهد، اما چیزی که در این مقاله ساخته‌ایم یعنی ngrok در مقابل python manage.py runserver روی لپ‌تاپ شخصی معماری Production نیست. runserver از طرف Django فقط برای Development در نظر گرفته شده است.

اشتراک‌گذاری

لینک را کپی کنید یا مقاله را در تلگرام، واتساپ و لینکدین بفرستید.

نویسنده
م

محمدهادی حاجی‌حسینی

نویسنده مقالات آموزشی کدینگ‌یار

دوره‌های مرتبط

یادگیری عمیق‌تر با دوره‌های پروژه‌محور

مقالات VIP

در هر دوره‌ای شرکت کنید، به محتوای اختصاصی همان دوره دسترسی پیدا می‌کنید.