Firebase SQL Connect Admin SDK ช่วยให้คุณเรียกใช้คําค้นหาและการเปลี่ยนแปลงจาก สภาพแวดล้อมที่เชื่อถือได้ เช่น Cloud Functions, แบ็กเอนด์ที่กําหนดเอง หรือ เวิร์กสเตชันของคุณเอง คุณสามารถสร้าง Admin SDK ที่กําหนดเองไปพร้อมๆ กับการออกแบบสคีมา คําค้นหา และการเปลี่ยนแปลงที่จะนําไปใช้กับบริการ SQL Connect ได้ในลักษณะเดียวกับที่คุณสร้าง SDK สําหรับแอปไคลเอ็นต์ จากนั้นผสานรวมเมธอดจาก SDK นี้เข้ากับตรรกะแบ็กเอนด์หรือสคริปต์การดูแลระบบ
ดังที่เราได้กล่าวไว้ในส่วนอื่นๆ สิ่งสําคัญที่ต้องทราบคือไคลเอ็นต์จะไม่ส่งคําค้นหาSQL Connect และการเปลี่ยนแปลงในเวลาที่ส่งคําขอ แต่เมื่อมีการนําไปใช้ ระบบจะจัดเก็บการดําเนินการของ SQL Connect ไว้ในเซิร์ฟเวอร์ เช่น Cloud Functions. ซึ่งหมายความว่าทุกครั้งที่คุณนําการเปลี่ยนแปลงไปใช้กับคําค้นหาและการเปลี่ยนแปลง คุณจะต้องสร้าง Admin SDK ขึ้นมาใหม่และนําบริการที่ต้องใช้ SDK เหล่านั้นไปใช้ใหม่ด้วย
ก่อนเริ่มต้น
- ดูข้อมูลเกี่ยวกับการออกแบบSQL Connectสคีมา คําค้นหา และการเปลี่ยนแปลง ในเวิร์กโฟลว์ทั่วไป คุณจะพัฒนาสิ่งเหล่านี้ไปพร้อมๆ กับโค้ดแอปพลิเคชัน รวมถึงบริการที่ใช้ Admin SDK
รวม Admin SDK สําหรับ Node.js เป็นทรัพยากร Dependency ในทุกที่ที่คุณวางแผนจะเรียกใช้ Admin SDK ที่สร้างขึ้น
สร้าง Admin SDK
หลังจากสร้างสคีมา คําค้นหา และการเปลี่ยนแปลงของ SQL Connect แล้ว คุณสามารถ สร้าง Admin SDK ที่เกี่ยวข้องได้โดยทำดังนี้
เปิดหรือสร้างไฟล์
connector.yamlแล้วเพิ่มคําจํากัดความadminNodeSdkconnectorId: default generate: adminNodeSdk: outputDir: ../../dataconnect-generated/admin-generated package: "@dataconnect/admin-generated" packageJsonDir: ../..โดยปกติแล้วไฟล์
connector.yamlจะอยู่ในไดเรกทอรีเดียวกับไฟล์ GraphQL (.gql) ที่มีคําจํากัดความของคําค้นหาและการเปลี่ยนแปลง หากคุณสร้าง Client SDK ไว้แล้ว ระบบจะสร้างไฟล์นี้ขึ้นมาแล้วสร้าง SDK
หากคุณติดตั้งส่วนขยาย SQL Connect VS Code ไว้ ส่วนขยายนี้จะอัปเดต SDK ที่สร้างขึ้นให้เป็นเวอร์ชันล่าสุดอยู่เสมอ
หรือใช้ Firebase CLI โดยทำดังนี้
firebase dataconnect:sdk:generateหรือหากต้องการสร้าง SDK ขึ้นมาใหม่โดยอัตโนมัติเมื่อคุณอัปเดตไฟล์
gqlให้ทำดังนี้firebase dataconnect:sdk:generate --watch
เรียกใช้การดําเนินการจาก Admin SDK
Admin SDK ที่สร้างขึ้นจะมีอินเทอร์เฟซและฟังก์ชันที่สอดคล้องกับคําจํากัดความ gql ซึ่งคุณสามารถใช้เพื่อดําเนินการกับฐานข้อมูลได้ ตัวอย่างเช่น สมมติว่าคุณสร้าง SDK สําหรับฐานข้อมูลเพลง พร้อมกับคําค้นหา getSongs
import { initializeApp } from "firebase-admin/app";
import { getSongs } from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const songs = await getSongs(
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
หรือหากต้องการระบุการกําหนดค่าตัวเชื่อมต่อ ให้ทำดังนี้
import { initializeApp } from "firebase-admin/app";
import { getDataConnect } from "firebase-admin/data-connect";
import {
connectorConfig,
getSongs,
} from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const adminDc = getDataConnect(connectorConfig);
const songs = await getSongs(
adminDc,
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
การสวมบทบาทเป็นผู้ใช้ที่ไม่มีการตรวจสอบสิทธิ์
Admin SDK ออกแบบมาให้ทํางานจากสภาพแวดล้อมที่เชื่อถือได้ จึงมีสิทธิ์เข้าถึงฐานข้อมูลของคุณแบบไม่จํากัด
เมื่อเรียกใช้การดําเนินการแบบสาธารณะด้วย Admin SDK คุณควรหลีกเลี่ยงการเรียกใช้การดําเนินการด้วยสิทธิ์ของผู้ดูแลระบบแบบเต็ม (ตามหลักการให้สิทธิ์ขั้นต่ำที่สุด) แต่คุณควรเรียกใช้การดําเนินการในฐานะผู้ใช้ที่สวมบทบาท (ดูส่วนถัดไป) หรือในฐานะผู้ใช้ที่ไม่มีการตรวจสอบสิทธิ์ที่สวมบทบาท
ผู้ใช้ที่ไม่มีการตรวจสอบสิทธิ์จะเรียกใช้ได้เฉพาะการดําเนินการที่ทําเครื่องหมายเป็น PUBLIC
ในตัวอย่างด้านบน ระบบจะเรียกใช้คําค้นหา getSongs ในฐานะผู้ใช้ที่ไม่มีการตรวจสอบสิทธิ์
การสวมบทบาทเป็นผู้ใช้
นอกจากนี้ คุณยังดําเนินการในนามของผู้ใช้ที่เฉพาะเจาะจงได้ด้วยการส่งFirebase Authenticationโทเค็นบางส่วนหรือ
ทั้งหมดในตัวเลือก impersonate โดยคุณ
ต้องระบุ User-ID ของผู้ใช้ในคำกล่าวอ้าง `sub` อย่างน้อย (ซึ่งเป็นค่าเดียวกับค่าเซิร์ฟเวอร์
auth.uidที่คุณอ้างอิงได้ในการดําเนินการ GraphQL
SQL Connect)
เมื่อคุณสวมบทบาทเป็นผู้ใช้ การดําเนินการจะสําเร็จก็ต่อเมื่อข้อมูลผู้ใช้ที่คุณระบุผ่านการตรวจสอบสิทธิ์ที่ระบุไว้ในคําจํากัดความ GraphQL
หากคุณเรียกใช้ SDK ที่สร้างขึ้นจากปลายทางที่เข้าถึงได้แบบสาธารณะ สิ่งสําคัญคือปลายทางต้องมีการตรวจสอบสิทธิ์ และคุณต้องตรวจสอบความสมบูรณ์ของโทเค็นการตรวจสอบสิทธิ์ก่อนที่จะใช้โทเค็นดังกล่าวเพื่อสวมบทบาทเป็นผู้ใช้
เมื่อใช้ Cloud Functions ที่เรียกใช้ได้ ระบบจะตรวจสอบโทเค็นการตรวจสอบสิทธิ์ โดยอัตโนมัติ และคุณสามารถใช้โทเค็นดังกล่าวได้ตามตัวอย่างต่อไปนี้
import { HttpsError, onCall } from "firebase-functions/https";
export const callableExample = onCall(async (req) => {
const authClaims = req.auth?.token;
if (!authClaims) {
throw new HttpsError("unauthenticated", "Unauthorized");
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
หรือใช้เมธอด Admin SDK's verifyIdToken เพื่อตรวจสอบและถอดรหัส
โทเค็นการตรวจสอบสิทธิ์ ตัวอย่างเช่น สมมติว่าคุณใช้ฟังก์ชัน HTTP ธรรมดาเพื่อใช้ปลายทาง และส่งโทเค็น Firebase Authentication ไปยังปลายทางโดยใช้ส่วนหัว authorization ตามมาตรฐาน
import { getAuth } from "firebase-admin/auth";
import { onRequest } from "firebase-functions/https";
const auth = getAuth();
export const httpExample = onRequest(async (req, res) => {
const token = req.header("authorization")?.replace(/^bearer\s+/i, "");
if (!token) {
res.sendStatus(401);
return;
}
let authClaims;
try {
authClaims = await auth.verifyIdToken(token);
} catch {
res.sendStatus(401);
return;
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
คุณควรระบุ User-ID ที่ไม่ได้มาจากแหล่งที่มาที่ตรวจสอบได้เฉพาะเมื่อทํางานด้านการดูแลระบบที่แท้จริง เช่น การย้ายข้อมูล จากสภาพแวดล้อมที่ปลอดภัยและเข้าถึงได้แบบสาธารณะ
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
การเรียกใช้ด้วยสิทธิ์เข้าถึงแบบไม่จํากัด
หากคุณดําเนินการที่ต้องใช้สิทธิ์ระดับผู้ดูแลระบบ ให้ละเว้นพารามิเตอร์การสวมบทบาทจากการเรียกใช้
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
การดําเนินการที่เรียกใช้ด้วยวิธีนี้จะมีสิทธิ์เข้าถึงฐานข้อมูลอย่างสมบูรณ์ หากคุณมีคําค้นหาหรือการเปลี่ยนแปลงที่ต้องการใช้เพื่อวัตถุประสงค์ในการดูแลระบบเท่านั้น คุณควรกําหนดคําค้นหาหรือการเปลี่ยนแปลงเหล่านั้นด้วย Directive @auth(level: NO_ACCESS) การทําเช่นนี้จะช่วยให้เฉพาะผู้เรียกใช้ระดับผู้ดูแลระบบเท่านั้นที่เรียกใช้การดําเนินการเหล่านี้ได้