كيف تبني خادم مصادقة (Auth Server) خاص بك في أقل من 30 دقيقة باستخدام OpenAuth

ما هو OpenAuth؟

OpenAuth هو مزود مصادقة (Auth Provider) مفتوح المصدر ومبني على معايير OAuth 2.0 القياسية، مصمم لتعمل به تطبيقات الويب والموبايل والـ SPA وحتى الـ APIs الخارجية. الفكرة ببساطة: بدلاً من تضمين مكتبة مصادقة داخل كل تطبيق على حدة، تشغّل خادم مصادقة مركزي (Centralized Auth Server) واحد على بنيتك التحتية الخاصة، ويتولى هو كل عمليات تسجيل الدخول لكل تطبيقاتك — الويب، الموبايل، لوحات الإدارة الداخلية، وأي عميل آخر يتحدث OAuth.

لماذا تهتم بـ OpenAuth؟

تخيل أنك تبني منتجاً يحتوي على تطبيق ويب، تطبيق Flutter للموبايل، ولوحة تحكم داخلية للفريق. مع الحلول التقليدية مفتوحة المصدر، أنت مضطر لتضمين مكتبة مصادقة منفصلة داخل كل مشروع، وتكرار منطق تسجيل الدخول وإدارة التوكنات (Tokens) في كل مكان. أما إذا اخترت خدمة SaaS جاهزة مثل Auth0 أو Clerk، فأنت تدفع فاتورة شهرية متصاعدة، وتربط بياناتك الحساسة بخادم طرف ثالث لا تملك السيطرة الكاملة عليه.

OpenAuth يقدم مساراً ثالثاً: خادم مصادقة مركزي يعمل بالكامل على بنيتك التحتية، مصمم خصيصاً ليكون سهل الاستضافة الذاتية، ويمكن نشره على Node.js أو Bun أو AWS Lambda أو Cloudflare Workers. بما أنه يلتزم بمواصفات OAuth 2.0، فأي عميل (Client) يفهم OAuth يمكنه استخدامه مباشرة — سواء كان تطبيق React أو تطبيق Flutter أو حتى سكريبت بسيط.

نقطة مهمة يجب أن تعرفها قبل البدء: <cite index=”1-1″>OpenAuth لا يحاول حل مشكلة إدارة المستخدمين (User Management) بنفسه، لأن قواعد البيانات وطرق الوصول إليها تختلف بشكل كبير في عالم JavaScript</cite>. بدلاً من ذلك، بمجرد أن يثبت المستخدم هويته، يستدعي OpenAuth دالة Callback خاصة بك لتنفيذ منطق البحث عن المستخدم أو إنشائه بنفسك — وهذا يمنحك مرونة كاملة على الجانب الذي يهمك فعلاً.

كيف تبدأ؟

المكتبة مبنية فوق Hono، وهو إطار عمل ويب خفيف يعمل في أي بيئة تشغيل. لنبدأ بإعداد خادم مصادقة بسيط خطوة بخطوة.

1. استورد دالة issuer

import { issuer } from "@openauthjs/openauth"

هذه الدالة هي نقطة الدخول الرئيسية، وهي التي تُنشئ تطبيق Hono كاملاً بكل منطق المصادقة (Auth Logic) جاهزاً للنشر.

2. أضف مزودي المصادقة (Providers)

import { GithubProvider } from "@openauthjs/openauth/provider/github"

const app = issuer({
  providers: {
    github: GithubProvider({
      clientID: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
      scopes: ["user:email"],
    }),
  },
})

هنا نضيف مزود GitHub كـ Provider خارجي (Third-party Identity Provider)، ونمرر له بيانات الاعتماد (Client ID و Secret) بالإضافة إلى الصلاحيات (Scopes) المطلوبة. يمكنك بنفس الطريقة إضافة Google أو أي مزود آخر، أو استخدام مزود Password المدمج إذا كنت تفضّل تسجيل الدخول التقليدي بالبريد وكلمة المرور.

3. عرّف الـ Subjects

import { object, string } from "valibot"

const subjects = createSubjects({
  user: object({
    userID: string(),
    workspaceID: string(),
  }),
})

الـ Subjects (الكيانات) تحدد شكل البيانات التي سيحملها التوكن (Access Token) في النهاية — وهو عبارة عن JWT مُشفّر بهذه البيانات. استخدام مكتبة تحقق مثل valibot هنا يضمن أن البيانات صحيحة الشكل قبل إصدار التوكن.

مثال تطبيقي كامل

الآن نربط كل القطع معاً في دالة success، وهي الـ Callback الذي يُستدعى بمجرد نجاح المستخدم في تسجيل دخوله عبر أي Provider:

import { issuer } from "@openauthjs/openauth"
import { GithubProvider } from "@openauthjs/openauth/provider/github"
import { MemoryStorage } from "@openauthjs/openauth/storage/memory"
import { subjects } from "./subjects.js"

const app = issuer({
  providers: {
    github: GithubProvider({
      clientID: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
      scopes: ["user:email"],
    }),
  },
  subjects,
  storage: MemoryStorage(),
  async success(ctx, value) {
    let userID
    if (value.provider === "github") {
      console.log(value.tokenset.access)
      userID = "..." // ابحث عن المستخدم أو أنشئه في قاعدة بياناتك
    }
    return ctx.subject("user", {
      userID,
      workspaceID: "default",
    })
  },
})

export default app

كل سطر هنا له دور واضح: providers يحدد طرق تسجيل الدخول المسموحة، storage يحدد أين تُخزَّن التوكنات (هنا استخدمنا MemoryStorage للاختبار فقط)، وsuccess هو المكان الوحيد الذي تكتب فيه منطقك الخاص للبحث عن المستخدم أو إنشائه. بعد ذلك، يمكنك نشر نفس الملف على Cloudflare Workers أو AWS Lambda أو حتى Node.js عادي بتغيير بسيط في طريقة التصدير فقط.

من جهة العميل (Client)، ولنفترض أنك تبني تطبيق Flutter أو أي SPA، ستستخدم تدفق PKCE:

import { createClient } from "@openauthjs/openauth/client"

const client = createClient({
  clientID: "my-client",
  issuer: "https://auth.myserver.com",
})

const { challenge, url } = await client.authorize(redirectUri, "code", { pkce: true })

هذا الكود ينشئ عميل OAuth ويبدأ تدفق التفويض (Authorization Flow) مع تفعيل PKCE، وهو أمان إضافي ضروري في التطبيقات التي لا تملك خادماً خلفياً موثوقاً — كتطبيقات الموبايل والـ SPA.

نصائح ومزالق يجب تجنبها

  • لا تستخدم MemoryStorage في الإنتاج (Production): هي مخصصة للاختبار فقط لأنها تفقد البيانات عند إعادة التشغيل. على AWS استخدم DynamoDB، وعلى Cloudflare استخدم Cloudflare KV.
  • لا تخلط بين إدارة المستخدمين ومنطق OpenAuth: تذكر أن OpenAuth لا يخزّن ملفات تعريف المستخدمين (User Profiles)، فقط التوكنات وبيانات المصادقة الدنيا. أي بيانات إضافية عن المستخدم هي مسؤوليتك الكاملة داخل success.
  • خزّن التوكنات في HTTP-only Cookies عند استخدام SSR: تجنب تخزينها في localStorage في تطبيقات الخادم لتقليل مخاطر هجمات XSS.
  • راجع Scopes بعناية: كل صلاحية إضافية تطلبها من Provider خارجي مثل GitHub تزيد من سطح الهجوم المحتمل، فاطلب فقط ما تحتاجه فعلياً.
  • لا تنسَ /.well-known/oauth-authorization-server: هذا المسار يُنشأ تلقائياً ويمكنك استخدامه للتحقق من أن خادمك يعمل بشكل صحيح فور النشر.

الخلاصة والرأي

OpenAuth ليس بديلاً لكل حالة استخدام — إذا كنت تبني MVP سريعاً ولا تمانع الاعتماد على SaaS، فحل جاهز مثل Auth0 أو Clerk سيوفر عليك وقتاً في البداية. لكن إذا كان لديك أكثر من تطبيق واحد يحتاج مصادقة موحدة، أو كنت تهتم بالتحكم الكامل في بياناتك وتكلفة التشغيل على المدى الطويل، فـ OpenAuth خيار قوي جداً: مجاني، مبني على معايير مفتوحة، ويعمل مع أي إطار عمل تقريباً — سواء كنت مطور ويب أو تبني الواجهة الخلفية لتطبيق Flutter.

جرب الكود أعلاه في مشروع تجريبي صغير، وابدأ بمزود GitHub لأنه الأسهل إعداداً، ثم انتقل تدريجياً لمزودات أخرى حسب حاجتك.

openauth

اعجبك المقال : شاركه الآن
احمد علي
احمد علي

مطور تطبيقات هواتف ذكية باستخدام Flutter، وصانع محتوى تقني يكتب عن الذكاء الاصطناعي والبرمجة وتطورات التكنولوجيا الحديثة. أسعى لتبسيط الأفكار المعقدة ومشاركة خبرتي مع المهتمين بالمجال.

المقالات: 230

اترك ردّاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *