كيف اسمح للAPI فقط للحصول على المعلومات او ارسال المعلومات, و منع المستخدم من الدخول بالمتصفح فقط يستطيع ارسال او استقبال البيانات من API الخاص بالموقع؟
السماح لل API فقط Laravel
يمكنك أن تمنع الوصول المباشر من المتصفح بواسطة استخدام استخدام مفاتيح API أو التوكن حيث يتطلب الوصول رمزًا صالحًا يتم إرساله في الرؤوس (Headers). المتصفح العادي لا يرسل هذه الرموز افتراضيًا، مما يمنع الوصول غير المصرح به. يمكنك أيضًا استخدام وسيط (Middleware) مخصص للتحقق من الرؤوس أو إعدادات CORS بحيث تمنع استدعاء الـ API من مصادر غير مصرح بها (مثل متصفح يحاول تشغيل سكربت من موقع آخر).
وملاحظة مهمة وهي تجنب الاعتماد على User-Agent فهو غير موثوق، لأنه يمكن تزويره بسهولة.
الأفضل إجبار الطلبات على أن تكون من نوع JSON، لأنّ المتصفحات بشكل افتراضي تطلب محتوى HTML عند الدخول إلى رابط، بينما تطبيقات الموبايل أو المواقع الأخرى التي تتصل بالـ API ترسل ترويسة Header تسمى Accept: application/json
لذا تستطيع منع الدخول المباشر عبر المتصفح من خلال إنشاء Middleware يتحقق من وجود تلك الترويسة.
php artisan make:middleware ForceJsonResponse
ثم اذهب إلى الملف الذي تم إنشاؤه في app/Http/Middleware/ForceJsonResponse.php وقم بتعديل دالة handle لتصبح كالتالي:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ForceJsonResponse
{
public function handle(Request $request, Closure $next): Response
{
if (!$request->wantsJson()) {
return response()->json([
'status' => false,
'message' => 'Access denied. Only API requests are allowed.'
], 406); // 406 Not Acceptable
}
return $next($request);
}
}
وبدءًا من لارافل 11 وأعلى افتح ملف bootstrap/app.php وأضف الـ Middleware إلى قسم الـ API لتفعيله:
use App\Http\Middleware\ForceJsonResponse;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->api(prepend: [
ForceJsonResponse::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
وما سبق ليس كافٍ، فمن لديه خبرة بالبرمجة يستطيع تعديل الترويسات وتخطي الـ middleware، لذا ستحتاج إلى استخدام Laravel Sanctum.
بحيث يكون أي مسار داخل routes/api.php محمي بواسطة auth:sanctum أي من خلال Token، وإليك مثال لحماية مسار user
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
وبذلك حتى لو قام الشخص بوضع Accept: application/json، ولم يرسل Authorization: Bearer {TOKEN}، سيرفض لارافل الطلب.
سأشرح لك الفكرة أولًا، ثم الطرق العملية.
الفكرة الأساسية
لا يمكنك تقنيًا “منع المتصفح تمامًا” من الوصول للـ API،
لأن أي طلب API هو في النهاية طلب HTTP ويمكن تنفيذه من المتصفح أو أي أداة أخرى.
لكن ما يمكنك فعله هو:
جعل الـ API لا يستجيب إلا لطلبات صحيحة ومصرّح بها
وأي محاولة فتح الرابط مباشرة في المتصفح تكون عديمة الفائدة.
1. التحقق من الهوية (Authentication)
أهم خطوة.
استخدم:
- JWT
- Session + Cookies
- API Keys (لخدمات داخلية فقط)
الفكرة:
أي endpoint حساس:
GET /api/profile
لا يُرجع شيئًا إلا إذا أُرسل معه Token صالح.
مثال:
Authorization: Bearer <JWT_TOKEN>
بدون التوكن:
- يرجع 401 Unauthorized
- حتى لو فتحه المستخدم من المتصفح
2. تحديد من يُسمح له بالوصول (Authorization)
ليس كل مستخدم له نفس الصلاحيات.
مثال:
- مستخدم عادي
- طبيب
- Admin
تتحقق داخل السيرفر:
if (user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' })
}
3. تقييد CORS (مهم جدًا)
CORS لا يمنع الهجمات، لكنه يمنع الاستخدام غير الشرعي من المتصفحات.
في Express:
app.use(cors({
origin: 'https://your-frontend.com',
credentials: true
}))
هذا يسمح فقط لواجهة موقعك بالوصول للـ API من المتصفح.
4. منع عرض البيانات عند الطلب المباشر
لا تُرجع HTML أبدًا.
الـ API يجب أن يُرجع:
- JSON فقط
- Status Codes واضحة
مثال:
res.json({ data })
وعند فتح الرابط مباشرة:
سيظهر JSON بلا معنى للمستخدم العادي.
5. استخدام Middleware للحماية
مثال:
function authMiddleware(req, res, next) {
const token = req.headers.authorization
if (!token) return res.status(401).json({ error: 'Unauthorized' })
next()
}
app.get('/api/profile', authMiddleware, controller)
6. Rate Limiting
لمنع:
- التجريب العشوائي
- Brute Force
- Scraping
import rateLimit from 'express-rate-limit'
app.use('/api', rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
}))
7. حماية متقدمة (اختياري)
- HTTPS فقط
- CSRF Token (إن كنت تستخدم Cookies)
- Validation لكل Input
- عدم كشف رسائل الخطأ التفصيلية
الحقيقة المهمة
لا تحاول منع:
http://example.com/api/users
من الفتح في المتصفح
بل اجعل:
- فتحه بلا توكن = لا قيمة له
- فتحه بدون صلاحية = مرفوض
- أي طلب غير شرعي = مرفوض
وهكذا يصبح الـ API:
مفتوح شكليًا، مغلق فعليًا.
التعليقات