---
title: "المصادقة"
url: https://docs.growamal.com/ar/authentication/
language: ar
---

# المصادقة

يستخدم أمل مصادقة **Bearer JWT** بلا ملفات تعريف ارتباط للجلسات. يُقرَن رمز وصول **قصير العمر** برمز
تجديد **طويل العمر ومتدوّر**.

| الرمز | العمر | يُخزَّن أين | يتدوّر؟ |
|---|---|---|---|
| رمز الوصول | 15 دقيقة (`expiresIn: 900`) | لدى العميل فقط؛ بلا حالة | لا |
| رمز التجديد | 7 أيام | على الخادم | نعم، عند كل استخدام |

## التسجيل

`POST /api/auth/register` **للتمهيد فقط.** يُنشئ الاستدعاء الأول مسؤولًا بنطاق `SUPER` ويعيد زوج
رموز. بعد ذلك يُغلَق التسجيل: أي استدعاء لاحق يعيد `403` مع `code: "PERMISSION_DENIED"`.

`organizationId` مطلوب لكل دور **عدا** المسؤول الأول بنطاق `SUPER` الذي يحذفه. ويُنشأ كل المستخدمين
اللاحقين عبر [إنشاء المستخدمين](https://docs.growamal.com/ar/guides/provision-users/)، لا عبر التسجيل.

## تسجيل الدخول

`POST /api/auth/login` بجسم `{ email, password }` ← `200` `AuthTokensResponse`
(`{ accessToken, refreshToken, expiresIn, tokenType }`). تعيد بيانات الاعتماد الخاطئة `401`.

> **تنبيه:** **حماية القوة الغاشمة تعيد `401` + `Retry-After`، لا `429`.** بعد 5 محاولات فاشلة لكل بريد خلال 15
> دقيقة تُقفَل نقطة النهاية وتستجيب بـ `401` وترويسة `Retry-After` (عدد ثواني الانتظار). تظهر ترويسات
> `X-RateLimit-*` بعد أول محاولة فاشلة. لا تتوقّع `429` صريحًا من هذه الواجهة.

يوجد طلب دخول كامل مع استجابته (curl و TypeScript) في
[البدء السريع ← الخطوة 2](https://docs.growamal.com/ar/getting-started/).

## استخدام رمز الوصول

أرسل رمز الوصول مع كل طلب محمي:

```bash
curl https://localhost:3000/api/auth/me \
  -H "Authorization: Bearer <accessToken>"
```

يعيد `GET /api/auth/me` هويتك إضافةً إلى مصفوفة `permissions[]` التي تحكم كل نقطة نهاية (`MeResponse`).

## التجديد والتدوير

`POST /api/auth/refresh` بجسم `{ refreshToken }` ← `AuthTokensResponse` جديد. رموز التجديد تتدوّر:
يُلغى الرمز القديم عند الاستخدام. **إعادة استخدام رمز تجديد مُدوَّر تعيد `401` وتُلغي الجلسة** (كشف
سرقة). خزّن دائمًا أحدث رمز تجديد من آخر استجابة.

## تسجيل الخروج

`POST /api/auth/logout` (يتطلّب رمز وصول صالحًا) يُلغي الجلسة على الخادم. رموز الوصول غير قابلة للإلغاء
الفردي؛ فهي قصيرة العمر بحسب التصميم، لذا تنتهي ببساطة.

## إعادة تعيين كلمة المرور

تدفّق من خطوتين، آمن ضد التعداد:

1. `POST /api/auth/password-reset` بجسم `{ email }` ← **دائمًا `200`** (لا يكشف أبدًا إن كان البريد
   موجودًا) ← يُرسَل رابط سحري (صلاحية ساعة واحدة).
2. `POST /api/auth/password-reset/confirm` بجسم `{ token, newPassword }` ← يعيد تعيين كلمة المرور
   **ويُلغي كل الجلسات القائمة**.

## دخول الطالب بالرمز السريع

لسهولة الاستخدام في الصف الأول، يسجّل الطلاب الدخول بلا بريد أو كلمة مرور:

```bash
curl -X POST https://localhost:3000/api/auth/student/quickcode \
  -H "Content-Type: application/json" \
  -d '{ "quickCode": "472", "classId": "clx4z2k0u0000xyz1234abcde" }'
```

`POST /api/auth/student/quickcode` برمز سريع **من رقمين** (01–99) + **`classCode`** رمز الصف من 6 أرقام
يعيد زوج رموز بنطاق الطالب (`QuickCodeLoginResponse` مع `tokens` و`studentId` و`classId`). الرمزان
زوج اعتماد واحد: رمز الصف يصل داخل الرابط الذي يدفعه المعلّم (`/student-login?class=<classCode>`)،
ويكتب الطالب رمزه الخاص فقط.

- رمز الطالب **لكل صف** (فريد بين طلاب الصف الفعّالين، فيتّسع الصف لـ 99 طالبًا كحدّ أقصى) و**لا
  ينتهي أبدًا**؛ وهو أيضًا كلمة مرور الطالب في الدخول المنزلي.
- **رمز الصف صالح سنة كاملة (365 يومًا) من إصداره.** ويمكن تجديده يدويًا من لوحة رابط الصف إذا وصل الرابط إلى غير المعنيّين (أو
  `POST /api/classes/{classId}/login-code/rotate`)، ونسخ رابط منتهٍ يجدّده تلقائيًا. يتوقف الرابط
  القديم فورًا، ولا تتغيّر رموز الطلاب عند تجديد رمز الصف.
- رمز غير صالح أو منتهٍ (للطالب أو للصف) يعيد `401` مع `code: "QUICKCODE_INVALID_OR_EXPIRED"`؛ وكثرة
  المحاولات تعيد `401` مع `code: "QUICKCODE_RATE_LIMIT"`.
- `GET /api/auth/student/class-preview?classCode=` (عام ومحدود المعدّل) يعيد اسمَي الصف والمدرسة
  لصفحة الدخول؛ ورمز صف منتهٍ يعيد `410` مع `code: "CLASS_CODE_EXPIRED"`.
- صيغة الطلب المباشرة بـ `classId` مرفوضة في الإنتاج.

## تسجيل الدخول عبر Google

يستطيع المستخدمون المستوردون من نظام إدارة التعلم تسجيل الدخول بحساباتهم على Google. يستخدم التدفق
PKCE ورمز تسليم قصير العمر:

1. **البدء:** `GET /api/auth/google/start?loginHint=<email>` يعيد `{ redirectUrl }`. وجِّه متصفّح
   المستخدم إلى `redirectUrl`.
2. **إعادة التوجيه:** يعيد Google التوجيه إلى `GET /api/auth/google/callback`. يُصدر الخادم معاملَ
   `?code=` **لمرة واحدة لمدة 60 ثانية** ويعيد توجيه المتصفح إلى التطبيق.
3. **التبادل:** يُرسل التطبيق فورًا `POST` بـ `{ code }` إلى `POST /api/auth/google/exchange`
   ويستقبل `AuthTokensResponse` معياريًا.

> **تنبيه:** `GET /api/auth/google/start` يعيد `503` عندما لا يكون `GOOGLE_CLIENT_ID` مُضبَّطًا في البيئة.
> تتحكّم قائمة النطاقات المسموح بها (`allowedGoogleDomains` على سجل المؤسسة) في حسابات Google
> المقبولة.

## ما الموجود (وغير الموجود) في الرمز

يحمل الـ JWT الـ `userId` (`sub`) والـ `organizationId` (`orgId`) ورمز الدور (`role`) ومعرّف الجلسة
(`sid`)، إضافةً إلى مطالبتَي `iat`/`exp` المعيارية. لا يُدرَج اسم أو بريد أو صف. اقرأ هذه من
`GET /api/auth/me`. لا يوجد **تدوير لسرّ الرمز / مطالبة `sv`** في الموجة الأولى (مؤجَّل لموجة لاحقة)،
لا تبنِ على وجوده.
