امروزه بسیاری از اپلیکیشنهای موبایل برای نمایش اطلاعات، ثبت سفارش، مدیریت حساب کاربری و انجام عملیات مختلف به یک سرور مرکزی متصل میشوند. برای مثال، یک اپلیکیشن فروشگاهی باید بتواند فهرست محصولات را دریافت کند، اطلاعات کاربر را نمایش دهد و سفارشهای جدید را در سرور ثبت کند.
یکی از راهکارهای مناسب برای پیادهسازی چنین ارتباطی، استفاده از API است. فریمورک Laravel ابزارهای متعددی برای طراحی API، اعتبارسنجی درخواستها، مدیریت دسترسی کاربران و بازگرداندن پاسخهای استاندارد در اختیار توسعهدهندگان قرار میدهد.
در این مقاله یاد میگیریم چگونه یک API ساده اما قابل توسعه با Laravel بسازیم، اطلاعات را به فرمت JSON برگردانیم، ورودیهای کاربر را اعتبارسنجی کنیم و با استفاده از Laravel Sanctum دسترسی به بخشهای خصوصی API را کنترل کنیم.
API چیست و چرا برای اپلیکیشن موبایل به آن نیاز داریم؟
API مخفف Application Programming Interface است. در یک اپلیکیشن موبایل، API واسطهای است که امکان ارتباط برنامه با سرور را فراهم میکند.
فرض کنید یک اپلیکیشن اندرویدی یا iOS برای نمایش محصولات به اطلاعات پایگاه داده نیاز دارد. بهجای اینکه اپلیکیشن مستقیماً به دیتابیس متصل شود، درخواستی به API ارسال میکند. Laravel درخواست را پردازش کرده، اطلاعات موردنیاز را از پایگاه داده دریافت میکند و پاسخ را معمولاً در قالب JSON برمیگرداند.
این معماری چند مزیت مهم دارد:
- امنیت بیشتر: اطلاعات اتصال به پایگاه داده در اختیار اپلیکیشن موبایل قرار نمیگیرد.
- استفاده مجدد از منطق برنامه: اپلیکیشن اندروید، iOS و وب میتوانند از یک API مشترک استفاده کنند.
- توسعهپذیری: منطق تجاری در سمت سرور قرار میگیرد و تغییرات آن لزوماً به انتشار نسخه جدید اپلیکیشن نیاز ندارند.
- کنترل دسترسی: میتوان مشخص کرد هر کاربر به کدام اطلاعات و عملیات دسترسی داشته باشد.
- یکپارچگی: ارتباط با سرویسهای دیگر، مانند درگاه پرداخت، سامانه پیامکی یا سرویسهای خارجی، سادهتر میشود.
تفاوت API و وبسایت معمولی در Laravel
در یک وبسایت سنتی، Laravel ممکن است صفحه HTML را با Blade تولید کند و به مرورگر تحویل دهد. اما در API معمولاً پاسخ بهصورت JSON ارسال میشود تا اپلیکیشن موبایل بتواند آن را پردازش کند.
برای مثال، پاسخ یک API محصولات میتواند چنین ساختاری داشته باشد:
{
"data": [
{
"id": 1,
"name": "محصول نمونه",
"price": 250000
}
]
}
اپلیکیشن موبایل با دریافت این پاسخ میتواند اطلاعات را در رابط کاربری خود نمایش دهد.
نکته مهم این است که API صرفاً به معنای برگرداندن JSON نیست. یک API مناسب باید قرارداد مشخصی برای مسیرها، اعتبارسنجی، خطاها، احراز هویت و ساختار پاسخها داشته باشد.
مرحله اول: آمادهسازی پروژه Laravel
اگر از قبل پروژه Laravel دارید، میتوانید از همان استفاده کنید. در غیر این صورت، پروژه جدیدی ایجاد کنید:
composer create-project laravel/laravel mobile-api
cd mobile-api
سپس تنظیمات اتصال به پایگاه داده را در فایل .env انجام دهید.
در نسخههای جدید Laravel ممکن است مسیرهای API بهصورت پیشفرض فعال نباشند. برای نصب و فعالسازی ساختار API، در صورت پشتیبانی نسخه پروژه از این دستور استفاده کنید:
php artisan install:api
این دستور معمولاً فایل مسیرهای API و وابستگیهای لازم برای API و Sanctum را آماده میکند. رفتار دقیق دستور به نسخه Laravel بستگی دارد؛ بنابراین قبل از اجرا، نسخه پروژه و راهنمای رسمی همان نسخه را بررسی کنید.
برای مشاهده نسخه Laravel میتوانید اجرا کنید:
php artisan --version
پس از آمادهسازی پروژه، سرور توسعه را اجرا کنید:
php artisan serve
در محیط توسعه، آدرس پایه معمولاً http://127.0.0.1:8000 است. برای تست از یک دستگاه موبایل واقعی، باید از آدرس قابل دسترس آن دستگاه استفاده کنید؛ آدرس 127.0.0.1 روی موبایل به خود موبایل اشاره میکند، نه رایانه توسعهدهنده.
مرحله دوم: تعریف مسیر API
در Laravel مسیرهای API معمولاً در فایل routes/api.php تعریف میشوند.
برای مثال، میخواهیم یک مسیر بسازیم که فهرست محصولات را برگرداند:
use Illuminate\Support\Facades\Route;
Route::get('/products', function () {
return response()->json([
'data' => [
[
'id' => 1,
'name' => 'محصول نمونه',
'price' => 250000,
],
[
'id' => 2,
'name' => 'محصول دوم',
'price' => 400000,
],
],
]);
});
در بسیاری از پیکربندیهای استاندارد Laravel، پیشوند /api به مسیرهای این فایل اضافه میشود. بنابراین آدرس درخواست به این شکل خواهد بود:
GET /api/products
در این مثال برای ساده نگهداشتن آموزش، اطلاعات بهصورت ثابت تعریف شدهاند. در پروژه واقعی باید دادهها از مدل و پایگاه داده دریافت شوند.
برای مشاهده مسیرهای ثبتشده میتوانید اجرا کنید:
php artisan route:list --path=api
مرحله سوم: ایجاد Controller برای مدیریت درخواستها
قرار دادن تمام منطق برنامه داخل فایل Route برای پروژههای کوچک قابل قبول است، اما با افزایش قابلیتها مدیریت کد دشوار میشود. بهتر است منطق مربوط به هر بخش را در Controller قرار دهیم.
برای ساخت کنترلر محصولات دستور زیر را اجرا کنید:
php artisan make:controller Api/ProductController
سپس در فایل app/Http/Controllers/Api/ProductController.php متد زیر را قرار دهید:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
class ProductController extends Controller
{
public function index(): JsonResponse
{
return response()->json([
'data' => [
[
'id' => 1,
'name' => 'محصول نمونه',
'price' => 250000,
],
],
]);
}
}
حالا مسیر را به کنترلر متصل کنید:
use App\Http\Controllers\Api\ProductController;
use Illuminate\Support\Facades\Route;
Route::get('/products', [ProductController::class, 'index']);
به این ترتیب، درخواست دریافت محصولات به متد index ارسال میشود.
در پروژه واقعی بهتر است اطلاعات از مدل Eloquent دریافت شوند و برای کنترل دقیق ساختار پاسخ از API Resource استفاده کنید.
مرحله چهارم: دریافت اطلاعات از پایگاه داده
فرض کنید مدل Product از قبل در پروژه وجود دارد و جدول محصولات نیز ساخته شده است.
کنترلر را به این صورت تغییر دهید:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\JsonResponse;
class ProductController extends Controller
{
public function index(): JsonResponse
{
$products = Product::query()
->where('is_active', true)
->select(['id', 'name', 'price'])
->paginate(20);
return response()->json($products);
}
}
در این نمونه، فقط محصولات فعال دریافت میشوند و هر صفحه حداکثر ۲۰ رکورد دارد.
استفاده از صفحهبندی برای فهرستهای بزرگ اهمیت زیادی دارد؛ زیرا ارسال هزاران رکورد در یک درخواست میتواند مصرف حافظه، زمان پاسخ و حجم اینترنت اپلیکیشن را افزایش دهد.
همچنین نام فیلدهایی مانند is_active باید با ساختار واقعی جدول پروژه شما مطابقت داشته باشد.
مرحله پنجم: استفاده از API Resource
یکی از مشکلاتی که در پروژههای واقعی رخ میدهد، وابستگی مستقیم ساختار پاسخ API به ساختار دیتابیس است. اگر تمام مدل را بدون محدودیت برگردانید، ممکن است فیلدهایی که نباید در اختیار کاربر قرار بگیرند نیز در پاسخ ظاهر شوند.
Laravel API Resource به شما اجازه میدهد شکل خروجی را مشخص کنید.
ابتدا دستور زیر را اجرا کنید:
php artisan make:resource ProductResource
سپس فایل app/Http/Resources/ProductResource.php را به این شکل تنظیم کنید:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'price' => $this->price,
];
}
}
اکنون در کنترلر از Resource استفاده کنید:
use App\Http\Resources\ProductResource;
use App\Models\Product;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
public function index(): AnonymousResourceCollection
{
return ProductResource::collection(
Product::query()
->where('is_active', true)
->paginate(20)
);
}
با این روش، فقط فیلدهایی که در Resource تعریف کردهاید به پاسخ اضافه میشوند. این کار هم ساختار API را قابل کنترلتر میکند و هم احتمال افشای ناخواسته اطلاعات را کاهش میدهد.
مرحله ششم: دریافت داده از اپلیکیشن موبایل
اکنون میخواهیم APIای بسازیم که اطلاعات ارسالی اپلیکیشن موبایل را دریافت کند. برای نمونه، یک مسیر ثبت محصول تعریف میکنیم.
ابتدا کنترلر را ایجاد کنید:
php artisan make:controller Api/ExampleController
در متد مربوط به ثبت اطلاعات، دادهها را اعتبارسنجی کنید:
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:150'],
'price' => ['required', 'numeric', 'min:0'],
]);
// در پروژه واقعی اطلاعات معتبر را ذخیره کنید.
return response()->json([
'message' => 'اطلاعات با موفقیت اعتبارسنجی شد.',
'data' => $validated,
], 201);
}
سپس مسیر را ثبت کنید:
use App\Http\Controllers\Api\ExampleController;
Route::post('/example', [ExampleController::class, 'store']);
این مثال فقط دادهها را اعتبارسنجی و برمیگرداند و چیزی در دیتابیس ذخیره نمیکند. برای ثبت واقعی، باید از مدل مناسب استفاده کنید و قواعد مربوط به دسترسی کاربر و مجاز بودن عملیات را نیز بررسی کنید.
در API، اعتبارسنجی نامعتبر معمولاً با پاسخ HTTP 422 همراه میشود. اپلیکیشن موبایل باید این پاسخ را مدیریت کند و پیام خطای مناسب را به کاربر نشان دهد.
نکته امنیتی: هیچگاه به این دلیل که داده از اپلیکیشن موبایل ارسال شده است، آن را معتبر یا قابل اعتماد فرض نکنید. تمام ورودیها باید در سمت سرور اعتبارسنجی شوند.
مرحله هفتم: احراز هویت API با Laravel Sanctum
بسیاری از مسیرهای API نباید برای همه قابل دسترس باشند. برای مثال، کاربر باید بتواند اطلاعات حساب خودش را ببیند، اما نباید بتواند اطلاعات حساب سایر کاربران را دریافت کند.
برای پیادهسازی احراز هویت توکنمحور در APIهای موبایل، Laravel Sanctum یکی از گزینههای متداول است.
Sanctum برای احراز هویت مبتنی بر توکن مناسب است و در سناریوهای خاص، احراز هویت SPA مبتنی بر کوکی را نیز پشتیبانی میکند. برای اپلیکیشن موبایل بومی، معمولاً از توکنهای API استفاده میشود.
محافظت از مسیرها با middleware
فرض کنید مسیر زیر باید فقط برای کاربران احراز هویتشده در دسترس باشد:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::middleware('auth:sanctum')->get(
'/user',
function (Request $request) {
return response()->json([
'data' => $request->user(),
]);
}
);
در این مثال، اگر درخواست توکن معتبر نداشته باشد، کاربر به اطلاعات محافظتشده دسترسی نخواهد داشت.
در پروژه واقعی، بهتر است اطلاعات کاربر را از طریق Resource برگردانید تا فیلدهای حساس، مانند دادههای غیرضروری حساب، در پاسخ قرار نگیرند.
صدور توکن برای اپلیکیشن موبایل
پس از اینکه اطلاعات ورود کاربر بهدرستی بررسی شد، میتوانید یک توکن برای اپلیکیشن صادر کنید.
برای نمونه، در یک کنترلر ورود که از قبل ورودیها را اعتبارسنجی میکند، میتوان از منطق زیر استفاده کرد:
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
public function login(Request $request)
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required', 'string'],
]);
$user = User::where('email', $credentials['email'])->first();
if (
! $user ||
! Hash::check($credentials['password'], $user->password)
) {
throw ValidationException::withMessages([
'email' => ['اطلاعات ورود صحیح نیست.'],
]);
}
$token = $user->createToken('mobile-app')->plainTextToken;
return response()->json([
'token' => $token,
'token_type' => 'Bearer',
]);
}
این قطعه کد منطق اصلی بررسی اطلاعات و صدور توکن را نشان میدهد؛ برای استفاده در محیط واقعی باید آن را با محدودسازی دفعات تلاش ورود، سیاستهای وضعیت حساب، پاسخهای استاندارد و سایر کنترلهای امنیتی پروژه تکمیل کنید. همچنین باید Sanctum نصب و پیکربندی شده باشد.
توکن خام فقط هنگام صدور در اختیار کلاینت قرار میگیرد. اپلیکیشن باید آن را به شکل امن نگهداری کند و از قرار دادن آن در لاگها یا محلهای عمومی خودداری کند.
ارسال توکن همراه درخواست
پس از ورود موفق، اپلیکیشن موبایل باید توکن را در هدر درخواستهای محافظتشده ارسال کند:
Authorization: Bearer YOUR_TOKEN
Accept: application/json
بهجای YOUR_TOKEN، توکن واقعی صادرشده توسط سرور قرار میگیرد.
از این پس، Laravel میتواند کاربر مرتبط با توکن را شناسایی کند و middleware مربوط به احراز هویت، دسترسی به مسیر را کنترل کند.
خروج کاربر از API
برای خروج از حساب، میتوان توکن جاری را حذف کرد تا دیگر قابل استفاده نباشد:
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
public function logout(Request $request): JsonResponse
{
$request->user()
->currentAccessToken()
->delete();
return response()->json([
'message' => 'خروج با موفقیت انجام شد.',
]);
}
این روش زمانی مناسب است که درخواست با توکن شخصی Sanctum احراز هویت شده باشد. اگر از سازوکار دیگری استفاده میکنید، منطق خروج باید مطابق همان روش پیادهسازی شود.
همچنین حذف توکن جاری، سایر توکنهای فعال کاربر را حذف نمیکند. اگر قصد دارید کاربر از تمام دستگاهها خارج شود، باید همه توکنهای مجاز او را طبق سیاست امنیتی پروژه لغو کنید.
مرحله هشتم: تفاوت Authentication و Authorization
این دو مفهوم به یکدیگر مرتبطاند، اما وظایف متفاوتی دارند.
| مفهوم | پرسش اصلی | مثال |
|---|---|---|
| Authentication | کاربر چه کسی است؟ | بررسی اعتبار توکن ورود |
| Authorization | کاربر اجازه انجام چه کاری را دارد؟ | بررسی اینکه کاربر مالک سفارش است یا مدیر سیستم |
استفاده از auth:sanctum بهتنهایی تضمین نمیکند که کاربر به همه اطلاعات مجاز است دسترسی داشته باشد. این middleware فقط هویت کاربر را از طریق سازوکار احراز هویت بررسی میکند.
برای مثال، اگر کاربری شناسه یک سفارش متعلق به شخص دیگری را در URL وارد کند، باید در سمت سرور مالکیت سفارش یا مجوز دسترسی او بررسی شود. برای این کار میتوانید از Policy، Gate یا منطق مجوزدهی مناسب استفاده کنید.
مرحله نهم: استانداردسازی خطاها و پاسخهای API
اپلیکیشن موبایل باید بتواند موفقیت و شکست درخواستها را تشخیص دهد. استفاده درست از کدهای HTTP و ساختار پاسخ ثابت، توسعه کلاینت را سادهتر میکند.
چند کد پرکاربرد عبارتاند از:
| کد HTTP | کاربرد |
|---|---|
200 | درخواست با موفقیت انجام شده است |
201 | منبع جدیدی ایجاد شده است |
401 | کاربر احراز هویت نشده است |
403 | کاربر اجازه انجام عملیات را ندارد |
404 | منبع موردنظر پیدا نشده است |
422 | دادههای ارسالی اعتبارسنجی نشدهاند |
429 | محدودیت تعداد درخواستها فعال شده است |
500 | خطای داخلی سرور رخ داده است |
برای نمونه، در یک عملیات ثبت اطلاعات میتوانید پاسخ موفق را با کد 201 برگردانید. در صورت بروز خطا نیز بهتر است جزئیات حساس سیستم، مسیرهای داخلی فایلها یا اطلاعات محرمانه سرور را در اختیار کلاینت قرار ندهید.
مرحله دهم: نکات امنیتی مهم در ساخت API موبایل
ساخت API فقط به تعریف Route و Controller محدود نمیشود. اگر API قرار است در محیط واقعی استفاده شود، باید از ابتدا برای امنیت آن برنامهریزی کنید.
۱. استفاده از HTTPS
در محیط عملیاتی، ارتباط اپلیکیشن با API را از طریق HTTPS برقرار کنید تا اطلاعات در مسیر انتقال بهسادگی قابل مشاهده یا تغییر نباشند.
۲. اعتبارسنجی تمام ورودیها
حتی اگر اپلیکیشن موبایل محدودیتهایی برای فرمها دارد، ممکن است مهاجم مستقیماً به API درخواست ارسال کند. اعتبارسنجی نهایی باید در سرور انجام شود.
۳. محدودسازی دفعات ورود
برای جلوگیری از تلاشهای مکرر برای حدسزدن رمز عبور، روی مسیر ورود Rate Limiting اعمال کنید. در صورت نیاز، محدودیت را بر اساس حساب کاربری، IP یا ترکیبی از معیارها طراحی کنید.
۴. نگهداری امن توکن
توکن نباید در کد عمومی اپلیکیشن، فایلهای لاگ یا فضای ذخیرهسازی ناامن قرار گیرد. در اپلیکیشنهای موبایل از امکانات امن سیستمعامل برای نگهداری اطلاعات حساس استفاده کنید.
۵. بررسی مالکیت اطلاعات
صرفاً احراز هویت کافی نیست. هنگام نمایش، ویرایش یا حذف اطلاعات باید بررسی کنید که کاربر مجاز به انجام عملیات روی آن منبع باشد.
۶. جلوگیری از افشای اطلاعات
از برگرداندن مستقیم تمام فیلدهای مدلهای Eloquent خودداری کنید. API Resource به شما امکان میدهد اطلاعات خروجی را بهصورت صریح مشخص کنید.
۷. ثبت رویدادها بدون ذخیره اطلاعات محرمانه
برای بررسی مشکلات و تلاشهای مشکوک میتوانید از سیستم Log لاراول استفاده کنید، اما رمز عبور، توکن خام و اطلاعات حساس را در لاگها ذخیره نکنید.
مرحله یازدهم: تست API پیش از اتصال به اپلیکیشن
قبل از اینکه API را به اپلیکیشن اندروید یا iOS متصل کنید، بهتر است درخواستها را با ابزارهایی مانند Postman، Insomnia یا ابزارهای تست API بررسی کنید.
برای مسیر دریافت محصولات، یک درخواست GET به آدرس زیر ارسال کنید:
http://127.0.0.1:8000/api/products
برای تست مسیرهای محافظتشده، هدر Authorization را با توکن معتبر تنظیم کنید.
چکلیست پیشنهادی تست:
- [ ] دریافت فهرست محصولات بدون خطا
- [ ] بررسی صفحهبندی
- [ ] ارسال داده نامعتبر و بررسی پاسخ
422 - [ ] ارسال درخواست بدون توکن به مسیر محافظتشده
- [ ] ارسال درخواست با توکن نامعتبر
- [ ] بررسی مجوز دسترسی به اطلاعات کاربران دیگر
- [ ] بررسی خروج و لغو توکن
- [ ] تست محدودیت دفعات درخواست
- [ ] بررسی پاسخها در شرایط خطای سرور
برای پروژههای بزرگتر، این سناریوها را به Feature Test تبدیل کنید تا با هر تغییر در کد بتوانید رفتار API را بهصورت خودکار بررسی کنید.
جمعبندی
Laravel ابزارهای لازم برای ساخت APIهای قابل توسعه و امن را فراهم میکند. با تعریف مسیرها، استفاده از Controller، دریافت اطلاعات از Eloquent، اعتبارسنجی درخواستها و استانداردسازی پاسخها میتوانید یک API پایه برای اپلیکیشن موبایل ایجاد کنید.
برای بخشهای خصوصی نیز Laravel Sanctum امکان استفاده از توکنهای API را فراهم میکند. با این حال، احراز هویت تنها بخشی از امنیت API است؛ بررسی مجوزها، محدودسازی درخواستها، نگهداری امن توکنها و جلوگیری از افشای اطلاعات نیز باید در طراحی سیستم لحاظ شوند.
اگر قصد دارید API را در یک پروژه واقعی به کار بگیرید، بهتر است از ابتدا ساختار پاسخها، نسخهبندی API، مدیریت خطاها و تست خودکار را نیز در نظر داشته باشید.
سوالات متداول
آیا Laravel برای ساخت API اپلیکیشن اندروید و iOS مناسب است؟
بله. Laravel میتواند API مشترکی برای اپلیکیشنهای اندروید، iOS و سایر کلاینتها ارائه دهد. اپلیکیشنها از طریق HTTP درخواست ارسال میکنند و معمولاً پاسخ JSON دریافت میکنند.
برای احراز هویت API در Laravel از چه ابزاری استفاده کنیم؟
برای بسیاری از APIهای مبتنی بر توکن، Laravel Sanctum انتخاب مناسبی است. انتخاب نهایی باید بر اساس نوع کلاینت، نیازهای امنیتی و معماری پروژه انجام شود.
آیا برای ساخت API در Laravel حتماً باید Controller ایجاد کنیم؟
خیر. میتوانید منطق ساده را مستقیماً در Route بنویسید؛ اما برای پروژههای قابل توسعه، جداسازی منطق در Controller و استفاده از کلاسهایی مانند API Resource معمولاً ساختار مناسبتری ایجاد میکند.
آیا API باید حتماً JSON برگرداند؟
خیر، اما JSON یکی از رایجترین قالبها برای ارتباط بین اپلیکیشن موبایل و سرور است. قالب پاسخ باید با نیاز کلاینت و قرارداد API هماهنگ باشد.
آیا داشتن توکن معتبر به این معناست که کاربر اجازه دسترسی به همه اطلاعات را دارد؟
خیر. توکن معتبر هویت کاربر را مشخص میکند، اما مجوز دسترسی به منابع باید جداگانه بررسی شود. برای مثال، کاربر نباید صرفاً با تغییر شناسه سفارش بتواند اطلاعات سفارش دیگران را مشاهده کند.





