เมื่อสร้างแอปพลิเคชันใดๆ ที่เปิดเผยต่อสาธารณะ สิ่งที่สำคัญอย่างยิ่งคือการปกป้อง ข้อมูลที่จัดเก็บไว้ในระบบของคุณ สำหรับ LLM มีความขยันเป็นพิเศษ ที่จำเป็นเพื่อให้แน่ใจว่าโมเดลจะเข้าถึงเฉพาะข้อมูลที่ควรได้ การเรียกเครื่องมือ กำหนดขอบเขตอย่างเหมาะสมสำหรับผู้ใช้ที่เรียกใช้ LLM และระบบจะเริ่มเรียกใช้โฟลว์ เฉพาะแอปพลิเคชันไคลเอ็นต์ที่ได้รับการยืนยันแล้วเท่านั้น
Firebase Genkit มีกลไกในการจัดการนโยบายการให้สิทธิ์และ บริบทเหล่านี้ สำหรับโฟลว์ที่ทำงานบน Cloud Functions สำหรับ 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' },
}
);
เมื่อทำงานกับ UI การพัฒนา Genkit คุณสามารถส่งออบเจ็กต์การตรวจสอบสิทธิ์โดย
ป้อน 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 คุณจะระบุการตรวจสอบสิทธิ์นี้ได้
ใน UI หรือในบรรทัดคำสั่งที่มีแฟล็ก --auth
:
genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --auth '{"uid": "abc-def"}'
การผสานรวม Cloud Functions สำหรับ Firebase
ปลั๊กอิน Firebase ผสานรวมกับ Firebase Auth / Google ได้อย่างสะดวกสบาย Cloud Identity Platform รวมถึงการรองรับ Firebase App Check ในตัว
การให้สิทธิ์
Wrapper onFlow()
ที่ได้จากปลั๊กอิน Firebase จะทำงานกับ
Cloud Functions for Firebase
SDK ของไคลเอ็นต์
เมื่อใช้ SDK ส่วนหัว Firebase Auth จะรวมโดยอัตโนมัติเป็น
ตราบใดที่ไคลเอ็นต์ของแอปยังใช้
Firebase Auth SDK
คุณใช้ Firebase Auth เพื่อปกป้องขั้นตอนที่คุณกำหนดด้วย 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
เป็น
DeCodeIdToken
คุณสามารถเรียกออบเจ็กต์นี้ได้ทุกเมื่อผ่านทาง getFlowAuth()
ตามที่ระบุไว้
ที่ด้านบน เมื่อเรียกใช้ขั้นตอนนี้ระหว่างการพัฒนา คุณจะส่งออบเจ็กต์ผู้ใช้
ด้วยวิธีเดียวกัน
genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --auth '{"admin": true}'
โดยค่าเริ่มต้น ปลั๊กอิน Firebase Auth กำหนดให้ส่วนหัวการตรวจสอบสิทธิ์ส่งส่วนหัวการตรวจสอบสิทธิ์ แต่ในกรณีที่คุณต้องการ ให้อนุญาตการเข้าถึงที่ไม่มีการตรวจสอบสิทธิ์ การจัดการสำหรับผู้ใช้ที่ตรวจสอบสิทธิ์แล้ว (เช่น คุณลักษณะการขายต่อยอด) คุณจะสามารถ กำหนดค่านโยบายดังนี้
authPolicy: firebaseAuth((user) => {
if (user && !user.email_verified) {
throw new Error("Logged in users must have verified emails");
}
}, {required: false}),
เมื่อใดก็ตามที่คุณเปิดเผย Cloud Function กับอินเทอร์เน็ตในวงกว้าง
คุณต้องใช้กลไกการให้สิทธิ์บางอย่างเพื่อปกป้องข้อมูลของคุณ
และข้อมูลของลูกค้า อย่างไรก็ตาม มีบางครั้งที่คุณต้องการ
เพื่อติดตั้งใช้งาน Cloud Function โดยไม่ต้องตรวจสอบการให้สิทธิ์ตามโค้ด (เช่น
ฟังก์ชันของคุณไม่สามารถเรียกใช้ได้ทั่วโลก แต่ได้รับการปกป้องโดย
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 App Check เพียงเพิ่ม
ตัวเลือกการกำหนดค่าต่อไปนี้สำหรับ 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 คุณจะต้องมีวิธีตั้งค่าการตรวจสอบการให้สิทธิ์ของคุณเอง ไปพร้อมๆ กับขั้นตอนแบบเดิม คุณมีสองตัวเลือกดังนี้
ใช้เฟรมเวิร์กของเซิร์ฟเวอร์ตามต้องการ และส่งผ่านบริบทการตรวจสอบสิทธิ์
runFlow()
ตามที่ระบุไว้ข้างต้นใช้
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 ได้ที่ Cloud Run วิธีทำ
โปรดทราบว่า ถ้าคุณใช้ (1) ตัวเลือกการกำหนดค่า middleware
จะ
ถูกละเว้นโดย runFlow()