# المصادقة و OAuth

> مفاتيح API، OAuth 2.1 مع PKCE (إطلاق مستقل لـ SMART on FHIR)، معرف OpenID Connect id_token، نطاقات مرضى SMART v2، عمر الرموز، ودورة حياة الموافقة.

Source: https://developers.anpheros.com/ar/guides/authentication

تقبل منصة Anpheros ثلاثة أنواع من بيانات الاعتماد. كل طلب يحمل نوعًا واحدًا بالضبط.

| بيانات الاعتماد | تبدو كـ | من | يرى |
|---|---|---|---|
| مفتاح API | `sk_test_…` (بيئة تجريبية) / `sk_live_…` (إنتاج) | خادم المشروع | المرضى الذين أنشأهم المشروع (في البيئة التجريبية، بما في ذلك نسخته الخاصة من 30 مريضًا اصطناعيًا) |
| رمز وصول OAuth | `at_…` | تطبيق يعمل لمريض واحد بموجب موافقة | هذا المريض فقط، ضمن نطاقات SMART الممنوحة |
| رمز تعريف Firebase | JWT | مطور في لوحة التحكم، أو مريض في "الاتصالات" | مؤسساتهم الخاصة / سجلاتهم الخاصة |

أرسلها كـ `Authorization: Bearer <credential>` (تعمل مفاتيح API أيضًا كـ `X-Api-Key`).

## مفاتيح واجهة برمجة التطبيقات (API Keys)

*   تم إنشاؤها في لوحة التحكم أو عبر `POST /admin/projects/{id}/keys`؛ تُعرض مرة واحدة؛ تُخزن كـ SHA-256 hash.
*   النطاقات (Scopes): `read`، `write`. المفتاح لا يعبر أبدًا بيئة مشروعه (لا يمكن لـ `sk_test_` الوصول إلى بيانات الإنتاج والعكس صحيح).
*   يتم فرض حد المعدل لكل مفتاح (الافتراضي 600/دقيقة) على مستوى المنصة بأكملها (مخزن مشترك)، مع `Retry-After` على 429. يوجد أيضًا حد لكل عنوان IP يبلغ 600/دقيقة.
*   رؤوس اختيارية عند الكتابة (writes): `X-Anpheros-Author-Type`، `X-Anpheros-Author-Ref`، `X-Anpheros-Source-System`، `X-Anpheros-Origin-Id`، `X-Anpheros-Acting-As` (ممارس Practitioner/دور ممارس PractitionerRole **من دليلك الخاص**)، `X-Anpheros-On-Behalf-Of` (منظمة Organization **من دليلك الخاص**). تقوم هذه الرؤوس بملء Provenance.

## OAuth 2.1 (SMART on FHIR, standalone launch)
Discovery: `GET /.well-known/smart-configuration`.

1. `GET /oauth/authorize?response_type=code&client_id=…&redirect_uri=…&scope=…&state=…&code_challenge=…&code_challenge_method=S256[&purpose=treatment][&patient=<pairwise id>][&lang=ro]`
   يعرض صفحة الموافقة المستضافة. PKCE S256 إلزامي؛ يجب تسجيل `redirect_uri` بدقة.
2. يقوم المريض بتسجيل الدخول (Google أو البريد الإلكتروني عبر Firebase)، ويختار السجل (خاص به أو لأحد المعالين)، والمدة (30/90/180/365 يومًا) ويسمح بذلك. تصدر المنصة رمزًا لمرة واحدة (10 دقائق).
3. `POST /oauth/token` مع `grant_type=authorization_code&code=…&code_verifier=…&redirect_uri=…&client_id=…` (العملاء السريون يضيفون `client_secret`).
   الاستجابة: `access_token` (30 دقيقة)، `refresh_token` (30 يومًا، دوار)، `patient` (معرفك المزدوج للسجل)، `grant_id`، `scope`.
4. التحديث: `grant_type=refresh_token`. كل رمز تحديث يستخدم لمرة واحدة. **تقديم رمز تحديث مستخدم يلغي السلسلة بأكملها** (كشف السرقة). يتم رفض طلب تحديث مكرر متوازي وقد يلغي السلسلة أيضًا، لذا لا تقم بالدوران بشكل متزامن أبدًا.
5. الإلغاء: `POST /oauth/revoke` (رمز + client_id). إلغاء رمز التحديث يلغي أيضًا رموز الوصول الخاصة به.

تحمل استجابات الرموز `Cache-Control: no-store` و `Pragma: no-cache`، كما يتطلب SMART.

### OpenID Connect (`openid fhirUser`)
اطلب `openid fhirUser` جنبًا إلى جنب مع نطاقات المريض، وتحتوي استجابة الرمز أيضًا على `id_token`: JWT موقع بـ RS256، مع `iss` (عنوان URL الأساسي للمنصة)، `sub` (معرفك المزدوج للشخص)، `aud` (الخاص بك `client_id`)، `exp`، `iat` و `fhirUser` — عنوان URL المطلق لمورد المريض الخاص بالشخص، يمكن قراءته باستخدام رمز الوصول الذي تلقيته للتو. يقع الاكتشاف في `GET /.well-known/openid-configuration`؛ المفاتيح العامة في `GET /oauth/jwks` (`kid` في رأس الرمز). المعلمة `nonce` غير مدعومة بعد (وهي اختيارية في تدفق رمز التفويض). يتم قبول `launch/patient` و `offline_access`؛ الحقل `patient` في استجابة الرمز هو سياق التشغيل.

أنواع منح أخرى: `client_credentials` (عملاء سريون؛ يتصرف مثل مفتاح API)، ومنحة هوية الطرف الأول (عملاء موثوق بهم فقط).

### علامتك التجارية على صفحة الموافقة

يمكن للتطبيق عرض شعاره ولون التمييز الخاص به على صفحة الموافقة المستضافة. قم بتعيينها في وحدة التحكم
(Applications → Brand) أو باستخدام واجهة برمجة تطبيقات المسؤول:

```http
PUT /admin/applications/{application_id}/branding
{"logo": "data:image/png;base64,…", "brand_color": "#1D4ED8"}
```

- **الشعار:** صورة PNG أو JPEG أو WebP بصيغة URI للبيانات، تصل إلى 64 كيلوبايت. يتم فحص المحتوى، وليس النوع المعلن؛
  لا يتم قبول SVG. يتم تخزين الصورة مع التطبيق وتضمينها في الصفحة، لذا لا تقوم صفحة الموافقة بإجراء أي طلب إلى خوادمك.
- **لون التمييز:** `#RRGGBB`، يستخدم للزر الأساسي. يجب أن يحافظ النص الأبيض عليه على تباين لا يقل عن
  4.5:1 (WCAG AA)؛ يتم رفض الألوان الفاتحة.
- يبقى الحقل الذي تتركه فارغًا كما هو؛ `null` أو سلسلة فارغة تزيله.

يبقى باقي الصفحة دون تغيير: سطر "Secured by Anpheros Platform"، وقائمة اللغة العادية بما يطلبه التطبيق، وشعار TEST على مشاريع sandbox، لذا يمكن للأشخاص دائمًا معرفة أن الموافقة تحتفظ بها Anpheros. موصلات الذكاء الاصطناعي (MCP) تعرض دائمًا صفحة Anpheros بدون علامة تجارية للتطبيق.

### النطاقات
نطاقات المرضى SMART v2: `patient/<Type>.<cruds>` مع مرشح `?category=<code>` اختياري (المرشح الوحيد الذي يفرضه الخادم؛ يتم رفض أي مرشح آخر عند التفويض). `patient/*.rs` يقرأ كل شيء؛ `offline_access` يضيف رمز تحديث. بيانات المريض الوصفية والدليل قابلة للقراءة دائمًا بموجب منحة. نوع مورد خارج المنحة يعيد 403؛ مريض خارج المنحة يعيد 404.

### دورة حياة الموافقة
تنتهي صلاحية الموافقات تلقائيًا، ويمكن للمريض إلغاؤها في أي وقت (شاشة الاتصالات / `/me`)، ويتم تسجيل كل قراءة بموجب موافقة مع معرف التطبيق. إشعارات الويب `consent.granted` / `consent.revoked` تخطر المشروع.

## الأخطاء
401 credential unknown/expired · 403 credential exists but may not do this · 404 resource does not exist *for you* · 429 rate limited (`Retry-After`). See [`errors.md`](https://developers.anpheros.com/ar/guides/errors).
