SDK quản trị Firebase Data Connect cho phép bạn gọi các truy vấn và đột biến từ các môi trường đáng tin cậy như Cloud Functions, phần phụ trợ tuỳ chỉnh hoặc máy trạm của riêng bạn. Tương tự như cách tạo SDK cho các ứng dụng khách, bạn có thể tạo một SDK quản trị tuỳ chỉnh song song khi thiết kế các lược đồ, truy vấn và đột biến mà bạn triển khai cho dịch vụ Data Connect. Sau đó, bạn tích hợp các phương thức từ SDK này vào logic phần phụ trợ hoặc tập lệnh quản trị.
Như chúng tôi đã đề cập ở nơi khác, điều quan trọng cần lưu ý là các truy vấn Data Connect và đột biến không được gửi bởi các ứng dụng khách tại thời điểm yêu cầu. Thay vào đó, khi được triển khai, các hoạt động của Data Connect sẽ được lưu trữ trên máy chủ như Cloud Functions. Điều này có nghĩa là bất cứ khi nào triển khai các thay đổi đối với truy vấn và đột biến, bạn cũng cần tạo lại SDK quản trị và triển khai lại mọi dịch vụ dựa vào các SDK đó.
Trước khi bắt đầu
- Tìm hiểu về cách thiết kế lược đồ, truy vấn và đột biến của Data Connect. Trong quy trình làm việc điển hình, bạn sẽ phát triển các lược đồ, truy vấn và đột biến này song song với mã ứng dụng , bao gồm mọi dịch vụ sử dụng SDK quản trị.
- Cài đặt Giao diện dòng lệnh (CLI) của Firebase.
- Thêm SDK quản trị cho Node.js dưới dạng phần phụ thuộc ở bất cứ nơi nào bạn dự định gọi các SDK quản trị đã tạo.
Tạo SDK quản trị
Sau khi tạo lược đồ, truy vấn và đột biến của Data Connect, bạn có thể tạo một SDK quản trị tương ứng:
Mở hoặc tạo tệp
connector.yamlrồi thêm định nghĩaadminNodeSdk:connectorId: default generate: adminNodeSdk: outputDir: ../../dataconnect-generated/admin-generated package: "@dataconnect/admin-generated" packageJsonDir: ../..Tệp
connector.yamlthường nằm trong cùng thư mục với các tệp GraphQL (.gql) chứa định nghĩa truy vấn và đột biến. Nếu bạn đã tạo SDK ứng dụng khách, thì tệp này đã được tạo.Tạo SDK.
Nếu bạn đã cài đặt tiện ích Data Connect VS Code, tiện ích này sẽ luôn cập nhật các SDK đã tạo.
Nếu không, hãy sử dụng Firebase CLI:
firebase dataconnect:sdk:generateHoặc để tự động tạo lại SDK khi bạn cập nhật tệp
gql:firebase dataconnect:sdk:generate --watch
Thực thi các hoạt động từ SDK quản trị
SDK quản trị đã tạo chứa các giao diện và hàm tương ứng với
định nghĩa gql. Bạn có thể sử dụng các giao diện và hàm này để thực hiện các hoạt động trên cơ sở dữ liệu
. Ví dụ: giả sử bạn đã tạo một SDK cho cơ sở dữ liệu bài hát,
cùng với một truy vấn 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 } }
);
Hoặc để chỉ định cấu hình trình kết nối:
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 } }
);
Nhập vai người dùng chưa xác thực
SDK quản trị được thiết kế để chạy từ các môi trường đáng tin cậy, do đó, có quyền truy cập không hạn chế vào cơ sở dữ liệu của bạn.
Khi chạy các hoạt động công khai bằng SDK quản trị, bạn nên tránh chạy hoạt động với đầy đủ đặc quyền quản trị viên (theo nguyên tắc đặc quyền tối thiểu). Thay vào đó, bạn nên chạy hoạt động dưới dạng người dùng được nhập vai
(xem phần tiếp theo) hoặc dưới dạng người dùng chưa xác thực được nhập vai.
Người dùng chưa xác thực chỉ có thể chạy các hoạt động được đánh dấu là PUBLIC.
Trong ví dụ ở trên, truy vấn getSongs được thực thi dưới dạng người dùng chưa xác thực.
Nhập vai người dùng
Bạn cũng có thể thực hiện các hoạt động thay mặt cho những người dùng cụ thể bằng cách truyền một phần hoặc
toàn bộ mã thông báo Firebase Authentication trong tuỳ chọn impersonate. Tối thiểu, bạn
phải chỉ định mã nhận dạng người dùng của người dùng trong yêu cầu xác nhận phụ. (Đây là cùng một giá trị với giá trị máy chủ
auth.uid mà
bạn có thể tham chiếu trong các hoạt động Data Connect GraphQL.)
Khi bạn nhập vai người dùng, hoạt động sẽ chỉ thành công nếu dữ liệu người dùng mà bạn cung cấp vượt qua các bước kiểm tra xác thực được chỉ định trong định nghĩa GraphQL.
Nếu bạn đang gọi SDK đã tạo từ một điểm cuối có thể truy cập công khai, thì điều quan trọng là điểm cuối đó phải yêu cầu xác thực và bạn phải xác thực tính toàn vẹn của mã thông báo xác thực trước khi sử dụng mã thông báo đó để nhập vai người dùng.
Khi sử dụng có thể gọi Cloud Functions, mã thông báo xác thực sẽ tự động được xác minh và bạn có thể sử dụng mã thông báo đó như trong ví dụ sau:
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 } }
);
// ...
});
Nếu không, hãy sử dụng Admin SDK's verifyIdToken phương thức để xác thực và giải mã
mã thông báo xác thực. Ví dụ: giả sử điểm cuối của bạn được triển khai dưới dạng một
hàm HTTP thuần tuý và bạn đã truyền mã thông báo Firebase Authentication đến điểm cuối bằng tiêu đề authorization, như thường lệ:
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 } }
);
// ...
});
Chỉ khi thực hiện các tác vụ quản trị thực sự, chẳng hạn như di chuyển dữ liệu, từ một môi trường an toàn, không thể truy cập công khai, bạn mới nên chỉ định một mã nhận dạng người dùng không bắt nguồn từ một nguồn có thể xác minh:
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
Chạy với quyền truy cập không hạn chế
Nếu bạn đang thực hiện một hoạt động yêu cầu quyền cấp quản trị viên, hãy bỏ qua tham số nhập vai khỏi lệnh gọi:
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
Một hoạt động được gọi theo cách này có quyền truy cập đầy đủ vào cơ sở dữ liệu. Nếu có các truy vấn hoặc đột biến chỉ dùng cho mục đích quản trị,
bạn nên xác định các truy vấn hoặc đột biến đó bằng chỉ thị @auth(level: NO_ACCESS). Việc này
đảm bảo rằng chỉ những người gọi cấp quản trị viên mới có thể thực thi các hoạt động này.