জেনারেটেড অ্যাডমিন SDK ব্যবহার করুন

Firebase Data Connect অ্যাডমিন SDK-গুলো আপনাকে ক্লাউড ফাংশন, কাস্টম ব্যাকএন্ড বা আপনার নিজস্ব ওয়ার্কস্টেশনের মতো বিশ্বস্ত পরিবেশ থেকে আপনার কোয়েরি এবং মিউটেশন কল করার সুযোগ দেয়। ঠিক যেভাবে আপনি আপনার ক্লায়েন্ট অ্যাপের জন্য SDK তৈরি করেন, সেভাবেই আপনার Data Connect সার্ভিসে ডেপ্লয় করার জন্য স্কিমা, কোয়েরি এবং মিউটেশন ডিজাইন করার পাশাপাশি আপনি একটি কাস্টম অ্যাডমিন SDK তৈরি করতে পারেন। এরপর, আপনি এই SDK-এর মেথডগুলোকে আপনার ব্যাকএন্ড লজিক বা অ্যাডমিনিস্ট্রেশন স্ক্রিপ্টে ইন্টিগ্রেট করতে পারেন।

আমরা অন্যত্র যেমন উল্লেখ করেছি, এটা মনে রাখা গুরুত্বপূর্ণ যে ডেটা কানেক্ট কোয়েরি এবং মিউটেশনগুলো ক্লায়েন্টরা অনুরোধের সময় জমা দেয় না। পরিবর্তে, ডেপ্লয় করার সময়, ডেটা কানেক্ট অপারেশনগুলো ক্লাউড ফাংশনের মতো সার্ভারে সংরক্ষিত হয়। এর মানে হলো, যখনই আপনি আপনার কোয়েরি এবং মিউটেশনগুলোতে কোনো পরিবর্তন ডেপ্লয় করবেন, আপনাকে অ্যাডমিন SDK-গুলোও পুনরায় তৈরি করতে হবে এবং সেগুলোর উপর নির্ভরশীল যেকোনো সার্ভিস পুনরায় ডেপ্লয় করতে হবে।

শুরু করার আগে

অ্যাডমিন এসডিকে তৈরি করুন

আপনার ডেটা কানেক্ট স্কিমা, কোয়েরি এবং মিউটেশন তৈরি করার পরে, আপনি একটি সংশ্লিষ্ট অ্যাডমিন SDK জেনারেট করতে পারবেন:

  1. একটি connector.yaml ফাইল খুলুন বা তৈরি করুন এবং একটি adminNodeSdk ডেফিনিশন যোগ করুন:

    connectorId: default
    generate:
      adminNodeSdk:
        outputDir: ../../dataconnect-generated/admin-generated
        package: "@dataconnect/admin-generated"
        packageJsonDir: ../..
    

    connector.yaml ফাইলটি সাধারণত সেইসব GraphQL (.gql) ফাইলের সাথে একই ডিরেক্টরিতে পাওয়া যায়, যেগুলিতে আপনার কোয়েরি এবং মিউটেশন ডেফিনিশন থাকে। আপনি যদি ইতিমধ্যেই ক্লায়েন্ট SDK তৈরি করে থাকেন, তাহলে এই ফাইলটি আগে থেকেই তৈরি করা আছে।

  2. এসডিকে তৈরি করুন।

    আপনার যদি ডেটা কানেক্ট ভিএস কোড এক্সটেনশন ইনস্টল করা থাকে, তাহলে এটি তৈরি করা এসডিকে-গুলোকে সর্বদা হালনাগাদ রাখবে।

    অন্যথায়, Firebase CLI ব্যবহার করুন:

    firebase dataconnect:sdk:generate

    অথবা, আপনার gql ফাইলগুলি আপডেট করার সময় SDK গুলি স্বয়ংক্রিয়ভাবে পুনরায় তৈরি করতে:

    firebase dataconnect:sdk:generate --watch

অ্যাডমিন SDK থেকে অপারেশনগুলি সম্পাদন করুন

তৈরি করা অ্যাডমিন 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 } }
);

অপ্রমাণিত ব্যবহারকারীর ছদ্মবেশ ধারণ করা

অ্যাডমিন এসডিকে-গুলো বিশ্বস্ত পরিবেশ থেকে চালানোর জন্য তৈরি করা হয়েছে, এবং সেই কারণে আপনার ডেটাবেসগুলোতে এগুলোর অবাধ অ্যাক্সেস রয়েছে।

অ্যাডমিন SDK ব্যবহার করে পাবলিক অপারেশন চালানোর সময়, আপনার সম্পূর্ণ অ্যাডমিনিস্ট্রেটর প্রিভিলেজ দিয়ে অপারেশনটি চালানো এড়িয়ে চলা উচিত (লিস্ট প্রিভিলেজের নীতি অনুসরণ করে)। এর পরিবর্তে, আপনার অপারেশনটি হয় একজন ইমপারসোনেটেড ইউজার হিসেবে (পরবর্তী বিভাগ দেখুন), অথবা একজন ইমপারসোনেটেড আনঅথেনটিকেটেড ইউজার হিসেবে চালানো উচিত। আনঅথেনটিকেটেড ইউজাররা শুধুমাত্র PUBLIC হিসেবে চিহ্নিত অপারেশনগুলোই চালাতে পারে।

উপরের উদাহরণে, getSongs কোয়েরিটি একজন প্রমাণীকরণবিহীন ব্যবহারকারী হিসেবে চালানো হয়েছে।

একজন ব্যবহারকারীর ছদ্মবেশ ধারণ করা

আপনি impersonate অপশনে একটি Firebase Authentication টোকেনের অংশবিশেষ বা সম্পূর্ণটি পাস করে নির্দিষ্ট ব্যবহারকারীদের পক্ষ থেকেও অপারেশন সম্পাদন করতে পারেন; ন্যূনতমপক্ষে, আপনাকে sub claim-এ ব্যবহারকারীর ইউজার আইডি অবশ্যই উল্লেখ করতে হবে। (এই মানটি auth.uid সার্ভার ভ্যালুর মতোই, যা আপনি Data Connect GraphQL অপারেশনগুলিতে রেফারেন্স হিসেবে ব্যবহার করতে পারেন।)

যখন আপনি কোনো ব্যবহারকারীর ছদ্মবেশ ধারণ করেন, তখন অপারেশনটি তখনই সফল হবে, যদি আপনার দেওয়া ব্যবহারকারীর ডেটা আপনার 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 এর verifyIdToken মেথডটি ব্যবহার করুন। উদাহরণস্বরূপ, ধরুন আপনার এন্ডপয়েন্টটি একটি সাধারণ HTTP ফাংশন হিসাবে প্রয়োগ করা হয়েছে এবং আপনি প্রচলিত নিয়ম অনুযায়ী authorization হেডার ব্যবহার করে আপনার এন্ডপয়েন্টে Firebase Authentication টোকেনটি পাস করেছেন:

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 } }
    );

    // ...
});

শুধুমাত্র ডেটা মাইগ্রেশনের মতো প্রকৃত প্রশাসনিক কাজ একটি সুরক্ষিত ও অপ্রকাশ্য পরিবেশ থেকে করার সময়ই আপনার এমন একটি ইউজার আইডি উল্লেখ করা উচিত, যা কোনো যাচাইযোগ্য উৎস থেকে উদ্ভূত হয়নি।

// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
  undefined,
  { impersonate: { authClaims } }
);

অবাধ অ্যাক্সেস সহ চলছে

আপনি যদি এমন কোনো অপারেশন সম্পাদন করেন যার জন্য অ্যাডমিন স্তরের অনুমতির প্রয়োজন, তাহলে কলটি থেকে impersonate প্যারামিটারটি বাদ দিন:

await upsertSong(adminDc, {
  title: songTitle_one,
  instrumentsUsed: [Instrument.VOCAL],
});

এইভাবে কল করা একটি অপারেশনের ডাটাবেসে সম্পূর্ণ অ্যাক্সেস থাকে। আপনার যদি এমন কোয়েরি বা মিউটেশন থাকে যা শুধুমাত্র প্রশাসনিক উদ্দেশ্যে ব্যবহার করার জন্য তৈরি, তবে আপনার সেগুলিকে @auth(level: NO_ACCESS) নির্দেশিকা দিয়ে সংজ্ঞায়িত করা উচিত। এটি নিশ্চিত করে যে শুধুমাত্র অ্যাডমিন-স্তরের কলাররাই এই অপারেশনগুলি সম্পাদন করতে পারবে।