في بنية الخدمات المصغرة، كل خدمة تستدعي خدمات أخرى باستمرار. هذه الاستدعاءات الداخلية تحتاج مصادقة. إليك الأنماط التي نستخدمها في خوادم Go الإنتاجية.
في بنية الخدمات المصغرة، كل خدمة تستدعي خدمات أخرى باستمرار. خدمة الطلبات تستدعي خدمة الفواتير. خدمة الفواتير تستدعي خدمة الإشعارات. هذه الاستدعاءات الداخلية تحتاج مصادقة: الخدمة التي تقبل طلبات داخلية بدون مصادقة تصبح سطح هجوم.
مشكلة عدم فعل أي شيء
النهج الأكثر شيوعاً في بداية مشاريع الخدمات المصغرة هو عدم وجود مصادقة داخلية. الخدمات تعمل داخل VPC، ومجموعة الأمان تسمح بالمرور فقط من الخدمات الأخرى في نفس VPC، فلماذا تضيف عبء المصادقة؟
هذا يفشل بطريقتين: أولاً، أمان المحيط الشبكي وحده ليس دفاعاً متعمقاً. إذا تعرضت أي خدمة للاختراق، يمكنها استدعاء أي خدمة أخرى بدون متطلبات بيانات اعتماد. ثانياً، عند البدء في إضافة نقاط نهاية جديدة وإدراك حاجتك لمعرفة أي مستدعٍ يُجري الطلب، يتعين عليك إضافة المصادقة بأثر رجعي لكل خدمة.
الخيار الأول: سر مشترك في الترويسات (الأبسط)
النهج الأبسط: كل خدمة داخلية مُهيَّأة بنفس السر، يُمرَّر كترويسة في جميع الاستدعاءات الداخلية.
// في المستدعي
func (c *InternalClient) do(ctx context.Context, req *http.Request) (*http.Response, error) {
req.Header.Set("X-Internal-Token", c.internalToken)
return c.httpClient.Do(req.WithContext(ctx))
}
// في middleware الخدمة المستقبِلة
func InternalAuthMiddleware(token string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("X-Internal-Token") != token {
http.Error(w, `{"error":"unauthorized"}`, http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
}
الرمز يأتي من متغير بيئة، يُحقن في تعريف مهمة ECS من AWS Secrets Manager. هذا النهج مناسب لعمليات النشر الصغيرة حيث جميع الخدمات يتحكم فيها نفس الفريق.
الخيار الثاني: رموز JWT قصيرة الأجل لكل خدمة
للخوادم التي تحتوي على أكثر من خمس خدمات أو حيث تحتاج لمعرفة أي مستدعٍ أجرى الطلب، الرموز المميزة JWT قصيرة الأجل لكل خدمة هي نمط أفضل.
كل خدمة مُهيَّأة بهويتها الخاصة ومفتاح توقيع مشترك. عند استدعاء خدمة أخرى، تُولِّد رمزاً JWT قصير الأجل يُعرِّف هويتها:
func GenerateServiceToken(signingKey []byte, serviceName string) (string, error) {
claims := ServiceTokenClaims{
Service: serviceName,
Scope: "internal",
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(5 * time.Minute)),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(signingKey)
}
لتجنب عبء توقيع JWT في كل طلب، نخزن الرمز في الذاكرة ونُجدده قبيل انتهاء صلاحيته:
func (c *TokenCache) Get() (string, error) {
c.mu.Lock()
defer c.mu.Unlock()
if time.Until(c.expiresAt) > 30*time.Second {
return c.token, nil
}
// توليد رمز جديد
tok, err := GenerateServiceToken(c.signingKey, c.serviceName)
if err != nil {
return "", err
}
c.token = tok
c.expiresAt = time.Now().Add(5 * time.Minute)
return c.token, nil
}
الخيار الثالث: التوقيع HMAC (لسلامة الطلب)
للعمليات المالية أو العمليات التي تحتاج للتحقق من عدم تعديل جسم الطلب أثناء الإرسال، يُضيف توقيع HMAC تجزئة تغطي طريقة الطلب والمسار وتجزئة الجسم والطابع الزمني.
هذا أثقل في التنفيذ ويضيف زمن استجابة. استخدمه فقط عندما تهم سلامة جسم الطلب، وليس كإعداد افتراضي لجميع الاستدعاءات الداخلية.
ما نتخطاه: mTLS وشبكات الخدمات
الـ mTLS يوفر هوية تشفيرية قوية للخدمات. شبكات الخدمات مثل Istio أو Linkerd تُؤتمت mTLS على مستوى البنية التحتية. لمعظم فرق SaaS في لبنان والشرق الأوسط التي تعمل بفرق هندسية صغيرة، التعقيد التشغيلي لشبكة الخدمات غير مبرر بالمقارنة مع المكاسب الأمنية على مصادقة JWT أو HMAC المطبقة بشكل صحيح.
رموز JWT المخزنة في Secrets Manager والمحقونة عبر تعريفات مهام ECS تحقق معظم ضمانات الأمان بجزء صغير من التكلفة التشغيلية.
فصل نقاط النهاية الداخلية والخارجية
لا تعرض نقاط النهاية الداخلية على نفس المنفذ أو مساحة المسار كنقاط النهاية الخارجية المواجهة للعملاء. نمط نظيف: نقاط النهاية الداخلية على منفذ منفصل مثل 8081 لا تعرضه مجموعة أمان ALB للإنترنت، فقط لمجموعة أمان VPC الخاصة بالخدمة.
دروس من بيئات الإنتاج
- احرص دائماً على مصادقة استدعاءات الخدمات الداخلية. المحيط الشبكي وحده ليس دفاعاً كافياً.
- للنشر الصغير، سر مشترك في Secrets Manager عملي وكافٍ.
- للنشر الأكبر، رموز JWT قصيرة الأجل لكل خدمة تمنحك هوية المستدعي وتسهل التنقيح.
- تخزين الرموز في الذاكرة وتجديدها قبيل انتهاء الصلاحية يتجنب عبء التوقيع في كل طلب.
نبني خوادم Go للخدمات المصغرة الإنتاجية للشركات في لبنان وعبر الشرق الأوسط. إذا كنت تصمم نموذج الأمان للخدمات الداخلية، يمكننا المساعدة. تواصل معنا عبر https://voxire.com/get-a-quote/



