التفويض والتكامل

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

توفِّر حزمة Firebase Genkit آليات لإدارة سياسات التفويض والسياقات. بالنسبة إلى التدفقات التي يتم تشغيلها على دوال Cloud لبرنامج Firebase، يمكن للمطوِّرين مطلوبة لتقديم سياسة مصادقة أو تقرُّ صراحةً بعدم واحد. بالنسبة إلى مسارات غير الدوال، يمكن إدارة المصادقة وضبطها أيضًا، ولكنها تتطلب المزيد من الدمج اليدوي.

تفويض التدفق الأساسي

يمكن أن تحدّد جميع التدفقات authPolicy في الإعدادات. تُعد سياسة المصادقة وظيفة تختبر ما إذا تم استيفاء معايير معينة (حددتها أنت)، وتطرح استثناءً في حالة فشل أي اختبار. إذا تم ضبط هذا الحقل، يتم تنفيذه قبل استدعاء المسار:

import { defineFlow, runFlow } from '@genkit-ai/flow';

export const selfSummaryFlow = defineFlow(
  {
    name: 'selfSummaryFlow',
    inputSchema: z.object({uid: z.string()}),
    outputSchema: z.string(),
    authPolicy: (auth, input) => {
      if (!auth) {
        throw new Error('Authorization required.');
      }
      if (input.uid !== auth.uid) {
        throw new Error('You may only summarize your own profile data.');
      }
    }
  },
  async (input) => { ... });

عند تنفيذ هذه العملية، عليك توفير عنصر مصادقة باستخدام withLocalAuthContext وإلا عليك تلقي رسالة خطأ:

// Error: Authorization required.
await runFlow(selfSummaryFlow, { uid: 'abc-def' });

// Error: You may only summarize your own profile data.
await runFlow(
  selfSummaryFlow,
  { uid: 'abc-def' },
  {
    withLocalAuthContext: { uid: 'hij-klm' },
  }
);

// Success
await runFlow(
  selfSummaryFlow,
  { uid: 'abc-def' },
  {
    withLocalAuthContext: { uid: 'abc-def' },
  }
);

عند التشغيل باستخدام واجهة مستخدم تطوير Genkit، يمكنك تمرير كائن Auth من خلال إدخال JSON في "Auth JSON" علامة التبويب: {"uid": "abc-def"}.

يمكنك أيضًا استرداد سياق المصادقة للخطوات في أي وقت خلال العملية. من خلال استدعاء getFlowAuth()، بما في ذلك الدوال التي تم استدعاءها بواسطة المسار:

import { getFlowAuth, defineFlow } from '@genkit-ai/flow';

async function readDatabase(uid: string) {
  if (getFlowAuth().admin) {
    // Do something special if the user is an admin:
    ...
  } else {
    // Otherwise, use the `uid` variable to retrieve the relevant document
    ...
  }
}

export const selfSummaryFlow = defineFlow(
  {
    name: 'selfSummaryFlow',
    inputSchema: z.object({uid: z.string()}),
    outputSchema: z.string(),
    authPolicy: ...
  },
  async (input) => {
    ...
    await readDatabase(input.uid);
  });

عند اختبار التدفقات باستخدام أدوات مطوّري البرامج Genkit، يمكنك تحديد هذه المصادقة. في واجهة المستخدم أو في سطر الأوامر الذي يحمل العلامة --auth:

genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --auth '{"uid": "abc-def"}'

دمج وظائف السحابة الإلكترونية مع Firebase

يوفّر مكوّن Firebase الإضافي تكاملاً مريحًا مع مصادقة Firebase أو Google. ومنصة Cloud Identity، وميزة "التحقّق من التطبيقات" المُدمَجة في Firebase

التفويض

يعمل برنامج تضمين onFlow() الذي يوفّره مكوّن Firebase الإضافي في الأصل مع وظائف السحابة الإلكترونية لبرنامج Firebase حِزم تطوير البرامج (SDK) للعملاء. عند استخدام حزمة تطوير البرامج (SDK)، سيتم تضمين رأس مصادقة Firebase تلقائيًا طالما أن برنامج تطبيقك يستخدم أيضًا حزمة تطوير البرامج (SDK) لمصادقة Firebase. يمكنك استخدام مصادقة Firebase لحماية مساراتك المحدّدة باستخدام onFlow():

import {firebaseAuth} from "@genkit-ai/firebase/auth";
import {onFlow} from "@genkit-ai/firebase/functions";

export const selfSummaryFlow = onFlow({
    name: "selfSummaryFlow",
    inputSchema: z.string(),
    outputSchema: z.string(),
    authPolicy: firebaseAuth((user) => {
      if (!user.email_verified && !user.admin) {
        throw new Error("Email not verified");
      }
    }),
  }, (subject) => {...})

عند استخدام المكوّن الإضافي لمصادقة Firebase، سيتم عرض user على أنّه DecodedIdToken: يمكنك استرداد هذا العنصر في أي وقت من خلال getFlowAuth() كما هو موضّح. أعلاه. عند تشغيل هذا التدفق أثناء التطوير، يمكنك تمرير كائن المستخدم بالطريقة نفسها:

genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --auth '{"admin": true}'

يتطلب المكوِّن الإضافي لمصادقة Firebase إرسال رأس المصادقة من خلال ولكن في الحالات التي تريد فيها السماح بالوصول غير المصادق عليه المناولة مع المستخدمين المصادَق عليهم (ميزات الارتقاء بالمبيعات، على سبيل المثال)، فيمكنك اضبط السياسة على النحو التالي:

authPolicy: firebaseAuth((user) => {
  if (user && !user.email_verified) {
    throw new Error("Logged in users must have verified emails");
  }
}, {required: false}),

عندما تعرض إحدى وظائف السحابة الإلكترونية على شبكة الإنترنت الأوسع نطاقًا، من الضروري استخدام نوع من آليات التفويض لحماية بياناتك وبيانات عملائك. ومع ذلك، هناك أوقات تحتاج فيها نشر دالة سحابية بدون عمليات تحقق من التفويض استنادًا إلى الرمز (على سبيل المثال، فإن الدالة ليست قابلة للاستدعاء عالميًا ولكنها محمية Cloud IAM). تشير رسالة الأشكال البيانية يكون الحقل authPolicy مطلوبًا دائمًا عند استخدام onFlow()، ولكن يمكنك إبلاغ المكتبة بأنّك تتوقّف عن التحقّق من الأذونات باستخدام الدالة noAuth():

import {onFlow, noAuth} from "@genkit-ai/firebase/functions";

export const selfSummaryFlow = onFlow({
    name: "selfSummaryFlow",
    inputSchema: z.string(),
    outputSchema: z.string(),
    // WARNING: Only do this if you have some other gatekeeping in place, like
    // Cloud IAM!
    authPolicy: noAuth(),
  }, (subject) => {...})

نزاهة العميل

المصادقة وحدها تُحدث تأثيرًا كبيرًا في حماية تطبيقك. لكنها أيضًا للتأكد من أن تطبيقات العميل فقط هي التي تستدعي أداء وظائفك. تشير رسالة الأشكال البيانية يتضمن مكوّن Firebase الإضافي في genkit دعمًا من الدرجة الأولى فحص التطبيقات من Firebase: ما عليك سوى إضافة خيارات الضبط التالية لجهاز onFlow():

import {onFlow} from "@genkit-ai/firebase/functions";

export const selfSummaryFlow = onFlow({
    name: "selfSummaryFlow",
    inputSchema: z.string(),
    outputSchema: z.string(),

    // These two fields for app check. The consumeAppCheckToken option is for
    // replay protection, and requires additional client configuration. See the
    // App Check docs.
    enforceAppCheck: true,
    consumeAppCheckToken: true,

    authPolicy: ...,
  }, (subject) => {...})

تفويض HTTP غير تابع لـ Firebase

عند نشر التدفقات إلى سياق خادم خارج Cloud Functions في ما يلي: لمنصة Firebase، فستحتاج إلى طريقة لإعداد عمليات التحقق من التفويض جنبًا إلى جنب مع التدفقات الأصلية. ويكون أمامك خياران:

  1. استخدِم أي إطار عمل للخادم، ومرِّر سياق المصادقة من خلال runFlow() كما هو موضّح أعلاه.

  2. يمكنك استخدام startFlowsServer() المدمَجة وتوفير البرمجيات الوسيطة Express في تهيئة التدفق:

    export const selfSummaryFlow = defineFlow(
    {
      name: 'selfSummaryFlow',
      inputSchema: z.object({uid: z.string()}),
      outputSchema: z.string(),
      middleware: [
        (req, res, next) => {
          const token = req.headers['authorization'];
          const user = yourVerificationLibrary(token);
    
          // This is what will get passed to your authPolicy
          req.auth = user;
          next();
        }
      ],
      authPolicy: (auth, input) => {
        if (!auth) {
          throw new Error('Authorization required.');
        }
        if (input.uid !== auth.uid) {
          throw new Error('You may only summarize your own profile data.');
        }
      }
    },
    async (input) => { ... });
    
    startFlowsServer();  // This will register the middleware
    

    لمزيد من المعلومات عن استخدام Express، يُرجى الاطّلاع على التشغيل في السحابة الإلكترونية على التعليمات

يُرجى ملاحظة أنّه في حال استخدام (1)، سيؤدي خيار ضبط middleware إلى: سيتم تجاهلها بواسطة runFlow().