---
type: tutorial
title: أعدّ بوّابة الوكيل مع nginx
summary: فعّل البوّابة على مفتاح موقع، وصِل وكيلًا عكسيًّا بـ nginx من طرف إلى طرف، وراقبها في وضع المعاينة قبل أن تحجب زائرًا حقيقيًّا واحدًا.
---

بنهاية هذا الدرس ستكون البوّابة تعمل أمام موقع خلف nginx: زائر غير مُمرَّر يُرسَل إلى لعبة، ولعبة محلولة تضبط كوكي، وطلبات لاحقة تمرّ مباشرةً. ستراقب الأمر كلّه أولًا في **وضع المعاينة**، فلا يُحجَب شيء حتى تؤكّد التوصيل. يُستخدَم هنا nginx؛ و[وصفات Traefik وCaddy وAuthelia](/docs/proxy-page-gate/reverse-proxy-recipes) تتبع الشكل نفسه.

<Callout type="tip">
افعل الخطوة 1 قبل أن تمسّ وكيلك. وضع المعاينة يدع البوّابة تعمل في المراقبة فقط: تسجّل لوحة التحكّم ما *كانت* ستفعله، لكن كل طلب لا يزال يمرّ، فخطأ توصيل لا يحبس أحدًا خارجًا أبدًا.
</Callout>

## 1. شغّل وضع المعاينة

في لوحة التحكّم، افتح الفريق وشغّل **وضع المعاينة**. وطوال تشغيله، يسجّل مُخوِّل البوّابة قرارات التحدّي مقابل المرور المباشر في [صفحة الإحصاءات](/docs/proxy-page-gate/statistics) لكنه لا يحجب أبدًا. ستطفئه في النهاية.

## 2. فعّل البوّابة على مفتاح موقعك

افتح مفتاح موقعك واذهب إلى صفحة **بوّابة الوكيل**. شغّل **الحالة ← مفعّل**، ثم اضبط:

- **مدّة السماح TTL**: كم من الوقت يمرّر حلٌّ واحد زائرًا (افتراضيًّا 30 دقيقة). الأقصر يعني فحوصًا أكثر لكن نافذة أصغر إن سُرِق كوكي.
- **وضع الفشل**: ما يفعله وكيلك حين لا يستطيع بلوغ مُخوِّل Caputchin. **الفشل المغلق** (fail closed) يحجب (أأمن لبوّابة تسجيل دخول)؛ و**الفشل المفتوح** (fail open) يمرّر الطلبات (يتفادى التوقّف على موقع عام).

تعرض الصفحة أيضًا مقتطف nginx جاهزًا للنسخ ومفتاح موقعك مملوء فيه سلفًا.

## 3. اسمح بالأصل الذي تغلقه ببوّابة

التحدّي لا يعيد التوجيه إلا إلى **أصل مسموح**، القائمة نفسها للأصول المسموحة التي تستخدمها الأداة. تأكّد أنها تشمل الأصل الذي تغلقه، مثلًا `https://auth.example.com`. اضبطه في إعداد Cap لمفتاح الموقع إن لم يكن موجودًا سلفًا.

## 4. صِل المُخوِّل وإعادة التوجيه إلى التحدّي

كتلتا `location`: طلب فرعي **مُخوِّل** داخلي، وإعادة توجيه **تحدٍّ** يقفز إليها الوكيل عند `401`. استبدِل `YOUR_SITE_KEY` بمفتاحك العامّ.

```nginx
# Gate the protected paths.
location / {
  auth_request /_cpt_authz;             # 204 = allow, 401 = challenge
  error_page 401 = @cpt_challenge;
  # ...proxy_pass to your app...
}

location = /_cpt_authz {
  internal;
  proxy_pass https://verify.caputchin.com/v1/gate/authz?site=YOUR_SITE_KEY;
  proxy_pass_request_body off;
  proxy_set_header Content-Length "";
  proxy_set_header Cookie $http_cookie;  # forward the cpt_gate cookie
}

location @cpt_challenge {
  return 302 https://verify.caputchin.com/v1/gate/challenge?site=YOUR_SITE_KEY&return=$scheme://$host$request_uri;
}
```

أغلِق مسارات الدخول ببوّابة (HTML البوّابة وPOST تسجيل الدخول). **لا** تغلق الطلب الفرعي للمُخوِّل، ولا فحوص السلامة، ولا ردّ النداء أدناه.

## 5. أضِف ردّ النداء الذي يضبط الكوكي

تنتهي صفحة التحدّي بإرسال ذاتي لـ `POST` صغير إلى `/__cpt/callback` على أصلك، مع `cpt_gate` (التصريح) و`to` (إلى أين يُرسَل الزائر) في **الجسم**. مُعالِج ضئيل يضبط الكوكي ويعيد التوجيه. العقد الكامل، بما فيه لِمَ تهمّ كل سمة كوكي، في [وصفات الوكيل العكسي](/docs/proxy-page-gate/reverse-proxy-recipes#the-callback). الحدّ الأدنى:

```js
app.post("/__cpt/callback", express.urlencoded({ extended: false }), (req, res) => {
  const pass = String(req.body.cpt_gate || "");
  const to = String(req.body.to || "/");
  const target = new URL(to, `https://${req.headers.host}`);
  if (target.host !== req.headers.host) return res.status(400).end(); // same-origin only
  res.setHeader(
    "Set-Cookie",
    `cpt_gate=${pass}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=1800`
  );
  res.redirect(303, target.pathname + target.search);
});
```

## 6. راقبها في المعاينة

حمّل الرابط المغلق. لأن المعاينة مشغّلة، تمرّ مباشرةً، لكن [صفحة الإحصاءات](/docs/proxy-page-gate/statistics) تسجّل `challenge_served` (لم يكن لديك كوكي) و، حالما تحلّ ويعمل ردّ النداء، `pass_issued`. أعِد التحميل ويُفترَض أن ترى `passthrough` يتسلّق. إن لم تظهر التحدّيات أبدًا، فكتلة المُخوِّل لا تُلمَس؛ وإن ردّ ردّ النداء بـ 400، فافحص أصل `to`.

## 7. انطلِق حيًّا

حين تبدو الأرقام صحيحة، أطفئ **وضع المعاينة**. تفرض البوّابة الآن: الزوّار غير المُمرَّرين يُرسَلون إلى اللعبة، والزوّار الذين حلّوا يتجوّلون حتى ينتهي تصريحهم.

## إلى أين بعد ذلك

- [وصفات الوكيل العكسي](/docs/proxy-page-gate/reverse-proxy-recipes): Traefik، وCaddy، وشرح Authelia الكامل.
- [إحصاءات بوّابة الوكيل](/docs/proxy-page-gate/statistics): ما الذي يعنيه كل رقم حالما تصير حيًّا.
- [نظرة عامة](/docs/proxy-page-gate/overview): الفكرة وما الذي لا تفعله البوّابة عمدًا.
