ahlan hamad

دليل OAuth معاينة

معاينة — غير متاح بعد. هذه الصفحة تصف تصميم خادم التفويض قيد البناء حتى تتمكن من التخطيط لتكاملك. لا يمكن استدعاء أي من نقاط النهاية أدناه الآن، وقد تتغير التفاصيل قبل الإطلاق.

عنوان الخادم ($AH_AUTH_HOST) ومدد صلاحية الرموز تُنشر عند الإطلاق. حتى ذلك الحين استخدم مفاتيح API.

نظرة عامة

نقطة النهايةالغرض
GET /oauth/authorizeشاشة الموافقة في متصفح المستخدم (بالعربية والإنجليزية)
POST /oauth/tokenاستبدال رمز التفويض، وتحديث الرموز (من خادمك)
POST /oauth/revokeإلغاء رمز (من خادمك)

1. سجّل تطبيقك

في لوحة المطوّر تنشئ تطبيقاً داخل مؤسسة المطوّر الخاصة بك وتحصل على client_id وclient_secret. السرّ يظهر مرة واحدة ويمكنك تدويره. سجّل روابط إعادة التوجيه بدقة — المطابقة حرفية — واختر الصلاحيات التي يطلبها التطبيق. التطبيق الجديد في وضع التطوير ويتصل فقط بشركات التجربة الخاصة بمؤسستك.

2. أرسل المستخدم إلى رابط التفويض

أنشئ code_verifier عشوائياً لكل محاولة واحتفظ به في خادمك، واحسب منه code_challenge، وأرسل state عشوائياً وتحقق منه عند العودة.

import crypto from "node:crypto";

// 1. A fresh verifier per authorization attempt; keep it server-side.
const codeVerifier = crypto.randomBytes(32).toString("base64url");
const codeChallenge = crypto
  .createHash("sha256")
  .update(codeVerifier)
  .digest("base64url");
const state = crypto.randomBytes(16).toString("base64url");

// 2. Send the user's browser here.
const url = new URL("/oauth/authorize", process.env.AH_AUTH_HOST);
url.search = new URLSearchParams({
  response_type: "code",
  client_id: process.env.AH_CLIENT_ID,
  redirect_uri: "https://yourapp.example/callback/ahlan-hamad",
  scope: "employees:read payroll:read",
  state,
  code_challenge: codeChallenge,
  code_challenge_method: "S256",
}).toString();
المعاملالقيمة
response_typecode
client_idمعرّف تطبيقك
redirect_uriأحد الروابط المسجلة، حرفياً
scopeصلاحيات مفصولة بمسافات، ضمن ما يطلبه التطبيق
stateقيمة عشوائية تتحقق منها عند العودة
code_challengeBASE64URL(SHA256(code_verifier))
code_challenge_methodS256

يسجّل المستخدم الدخول إلى أهلاً حمد. مستخدم لديه صلاحية integrations.manage يختار الشركة، ويرى اسم تطبيقك والصلاحيات المطلوبة، ثم يوافق أو يرفض. نعيده إلى رابطك:

https://yourapp.example/callback/ahlan-hamad?code=…&state=…
https://yourapp.example/callback/ahlan-hamad?error=access_denied&state=…

3. استبدل الرمز برموز

رمز التفويض صالح لاستخدام واحد ولمدة 60 ثانية. استبدله من خادمك مع نفس redirect_uri وcode_verifier.

curl -X POST "$AH_AUTH_HOST/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  -d redirect_uri="https://yourapp.example/callback/ahlan-hamad" \
  -d code_verifier="$CODE_VERIFIER" \
  -d client_id="$AH_CLIENT_ID" \
  -d client_secret="$AH_CLIENT_SECRET"
{
  "access_token": "…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "…",
  "scope": "employees:read payroll:read"
}

قيمة expires_in في المثال توضيحية؛ مدد الصلاحية تُحدَّد عند الإطلاق.

4. استدعِ الـ API

curl https://actions.ahlanhamad.com/v1/company \
  -H "Authorization: Bearer $ACCESS_TOKEN"

نفس نقاط النهاية ونفس فحص الصلاحيات ونفس حدّ الطلبات ونفس أخطاء problem+json كما مع مفاتيح API. رمز ملغى أو منتهي يُرجع 401 unauthenticated.

5. حدّث الرموز

curl -X POST "$AH_AUTH_HOST/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d grant_type=refresh_token \
  -d refresh_token="$REFRESH_TOKEN" \
  -d client_id="$AH_CLIENT_ID" \
  -d client_secret="$AH_CLIENT_SECRET"

6. الإلغاء

curl -X POST "$AH_AUTH_HOST/oauth/revoke" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d token="$REFRESH_TOKEN" \
  -d client_id="$AH_CLIENT_ID" \
  -d client_secret="$AH_CLIENT_SECRET"

ألغِ الرموز عندما يفصل العميل حسابه من منتجك. يستطيع العميل أيضاً إلغاء تطبيقك من صفحة التطبيقات المتصلة؛ عندها تتوقف الرموز فوراً ويُعطَّل الويب هوك الخاص بهذا الاتصال.

الصلاحيات

نفس صلاحيات مفاتيح API. GET /v1/company لا يحتاج صلاحية. اطلب أقل ما يحتاجه تكاملك — العميل يرى القائمة قبل الموافقة.

الصلاحيةتسمح بـ
employees:readعرض الموظفين وقراءتهم
payroll:readعرض مسيّرات الرواتب المغلقة وقراءتها (الإجماليات والقيد فقط)
attendance:readقراءة الحضور
attendance:writeإرسال حركات الحضور والانصراف
webhooks:manageتسجيل نقاط الويب هوك وإدارتها

لا يوجد أي مسار — مفتاح أو OAuth — يُرجع رواتب أو بدلات الموظفين الفردية.

الأخطاء

أخطاء /oauth/token و/oauth/revoke تتبع صيغة OAuth القياسية (RFC 6749 §5.2): error وerror_description. أخطاء رابط التفويض تُعاد إلى redirect_uri كمعاملات استعلام، إلا إذا كان الرابط نفسه أو client_id غير صالح، فتظهر للمستخدم ولا يُعاد توجيهه.

{
  "error": "invalid_grant",
  "error_description": "The authorization code has expired or was already used"
}
errorالمعنى
invalid_requestمعامل ناقص أو مكرر، أو رابط إعادة التوجيه لا يطابق حرفياً رابطاً مسجلاً للتطبيق.
invalid_clientمعرّف عميل غير معروف أو سرّ عميل خاطئ.
invalid_grantانتهت صلاحية الرمز (60 ثانية) أو استُخدم من قبل أو صدر لعميل أو رابط آخر؛ أو مُتحقق PKCE لا يطابق؛ أو رمز التحديث استُخدم من قبل أو أُلغي.
invalid_scopeصلاحية غير موجودة، أو أكثر مما طلبه التطبيق أو مُنح للاتصال.
unauthorized_clientلا يحق للتطبيق الاتصال بهذه الشركة — مثل تطبيق في وضع التطوير وشركة ليست من شركات التجربة الخاصة بك.
unsupported_grant_typeقيمة grant_type غير authorization_code أو refresh_token.
access_deniedتُعاد إلى رابط إعادة التوجيه عندما يرفض المستخدم.