בעזרת ה-SDK לאדמינים, אתם יכולים לקרוא ולכתוב נתונים ב-מסד נתונים בזמן אמת עם הרשאות אדמין מלאות, או עם הרשאות מוגבלות ומפורטות יותר. במסמך הזה נסביר איך להוסיף לפרויקט את ה-SDK של Firebase לאדמינים כדי לגשת אל Firebase Realtime Database.
הגדרת SDK לאדמינים
כדי להתחיל להשתמש במסד נתונים בזמן אמת ב-Firebase בשרת, קודם צריך להגדיר את Firebase Admin SDK בשפה הרצויה.
אימות SDK לאדמינים
כדי לגשת אל Firebase Realtime Database משרת באמצעות ה-SDK של Firebase לאדמינים, צריך לאמת את השרת ב-Firebase. כשמאמתים שרת, במקום להיכנס באמצעות פרטי הכניסה של חשבון משתמש כמו באפליקציית לקוח, מאמתים באמצעות חשבון שירות שמזהה את השרת ב-Firebase.
כשמבצעים אימות באמצעות ה-SDK של Firebase לאדמינים, אפשר לקבל שתי רמות גישה שונות:
| רמות גישה לאימות ב-SDK של Firebase לאדמינים | |
|---|---|
| הרשאות אדמין | גישה מלאה לקריאה ולכתיבה של Realtime Database בפרויקט. השתמשו בו בזהירות כדי להשלים משימות ניהוליות כמו העברת נתונים או ארגון מחדש, שדורשות גישה בלתי מוגבלת למשאבי הפרויקט. |
| הרשאות מוגבלות | גישה ל-Realtime Database של הפרויקט, שמוגבלת רק למשאבים שהשרת צריך. השתמשו ברמה הזו כדי להשלים משימות ניהוליות עם דרישות גישה מוגדרות היטב. לדוגמה, כשמריצים משימת סיכום שקוראת נתונים מכל מסד הנתונים, אפשר להגן מפני כתיבה מקרית על ידי הגדרת כלל אבטחה לקריאה בלבד, ואז להפעיל את SDK לאדמינים עם הרשאות שמוגבלות על ידי הכלל הזה. |
אימות באמצעות הרשאות אדמין
כשמאתחלים את ה-SDK של Firebase לאדמינים עם פרטי הכניסה של חשבון שירות עם התפקיד עריכה בפרויקט Firebase, למכונה הזו יש גישה מלאה לקריאה ולכתיבה ב-Realtime Database של הפרויקט.
Java
// Initialize the SDK with Application Default Credentials FirebaseOptions options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.getApplicationDefault()) // The database URL depends on the location of the database .setDatabaseUrl("https://DATABASE_NAME.firebaseio.com") .build(); FirebaseApp.initializeApp(options); // As an admin, the app has access to read and write all data, regardless of Security Rules DatabaseReference ref = FirebaseDatabase.getInstance() .getReference("restricted_access/secret_document"); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { Object document = dataSnapshot.getValue(); System.out.println(document); } @Override public void onCancelled(DatabaseError error) { } });
Node.js
import { initializeApp } from 'firebase-admin/app'; import { getDatabase } from 'firebase-admin/database'; // Initialize the app with Application Default Credentials, granting admin privileges initializeApp({ // The database URL depends on the location of the database databaseURL: "https://DATABASE_NAME.firebaseio.com" }); // As an admin, the app has access to read and write all data, regardless of Security Rules const db = getDatabase(); const ref = db.ref("restricted_access/secret_document"); ref.once("value", (snapshot) => { console.log(snapshot.val()); });
Python
import firebase_admin from firebase_admin import credentials from firebase_admin import db # Fetch the service account key JSON file contents cred = credentials.Certificate('path/to/serviceAccountKey.json') # Initialize the app with a service account, granting admin privileges firebase_admin.initialize_app(cred, { 'databaseURL': 'https://databaseName.firebaseio.com' }) # As an admin, the app has access to read and write all data, regradless of Security Rules ref = db.reference('restricted_access/secret_document') print(ref.get())
המשך
ctx := context.Background() conf := &firebase.Config{ DatabaseURL: "https://databaseName.firebaseio.com", } // Fetch the service account key JSON file contents opt := option.WithCredentialsFile("path/to/serviceAccountKey.json") // Initialize the app with a service account, granting admin privileges app, err := firebase.NewApp(ctx, conf, opt) if err != nil { log.Fatalln("Error initializing app:", err) } client, err := app.Database(ctx) if err != nil { log.Fatalln("Error initializing database client:", err) } // As an admin, the app has access to read and write all data, regradless of Security Rules ref := client.NewRef("restricted_access/secret_document") var data map[string]interface{} if err := ref.Get(ctx, &data); err != nil { log.Fatalln("Error reading from database:", err) } fmt.Println(data)
אימות עם הרשאות מוגבלות
השיטה המומלצת היא לתת לשירות גישה רק למשאבים שהוא צריך. כדי לקבל שליטה מדויקת יותר על המשאבים שמופע של אפליקציית Firebase יכול לגשת אליהם, צריך להשתמש במזהה ייחודי בכללי האבטחה כדי לייצג את השירות. לאחר מכן מגדירים כללים מתאימים שנותנים לשירות גישה למשאבים שהוא צריך. לדוגמה:
{
"rules": {
"public_resource": {
".read": true,
".write": true
},
"some_resource": {
".read": "auth.uid === 'my-service-worker'",
".write": false
},
"another_resource": {
".read": "auth.uid === 'my-service-worker'",
".write": "auth.uid === 'my-service-worker'"
}
}
}
לאחר מכן, בשרת, כשמפעילים את אפליקציית Firebase, משתמשים באפשרות databaseAuthVariableOverride כדי לשנות את האובייקט auth שבו משתמשים כללי מסד הנתונים. באובייקט auth המותאם אישית, מגדירים את השדה uid למזהה שבו השתמשתם כדי לייצג את השירות בכללי האבטחה.
Java
// Initialize the app with a custom auth variable, limiting the server's access Map<String, Object> auth = new HashMap<String, Object>(); auth.put("uid", "my-service-worker"); FirebaseOptions options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.getApplicationDefault()) // The database URL depends on the location of the database .setDatabaseUrl("https://DATABASE_NAME.firebaseio.com") .setDatabaseAuthVariableOverride(auth) .build(); FirebaseApp.initializeApp(options); // The app only has access as defined in the Security Rules DatabaseReference ref = FirebaseDatabase .getInstance() .getReference("/some_resource"); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { String res = dataSnapshot.getValue(); System.out.println(res); } });
Node.js
import { initializeApp } from 'firebase-admin/app'; import { getDatabase } from 'firebase-admin/database'; // Initialize the app with a custom auth variable, limiting the server's access initializeApp({ // The database URL depends on the location of the database databaseURL: "https://DATABASE_NAME.firebaseio.com", databaseAuthVariableOverride: { uid: "my-service-worker" } }); // The app only has access as defined in the Security Rules const db = getDatabase(); const ref = db.ref("/some_resource"); ref.once("value", (snapshot) => { console.log(snapshot.val()); });
Python
import firebase_admin from firebase_admin import credentials from firebase_admin import db # Fetch the service account key JSON file contents cred = credentials.Certificate('path/to/serviceAccountKey.json') # Initialize the app with a custom auth variable, limiting the server's access firebase_admin.initialize_app(cred, { 'databaseURL': 'https://databaseName.firebaseio.com', 'databaseAuthVariableOverride': { 'uid': 'my-service-worker' } }) # The app only has access as defined in the Security Rules ref = db.reference('/some_resource') print(ref.get())
המשך
ctx := context.Background() // Initialize the app with a custom auth variable, limiting the server's access ao := map[string]interface{}{"uid": "my-service-worker"} conf := &firebase.Config{ DatabaseURL: "https://databaseName.firebaseio.com", AuthOverride: &ao, } // Fetch the service account key JSON file contents opt := option.WithCredentialsFile("path/to/serviceAccountKey.json") app, err := firebase.NewApp(ctx, conf, opt) if err != nil { log.Fatalln("Error initializing app:", err) } client, err := app.Database(ctx) if err != nil { log.Fatalln("Error initializing database client:", err) } // The app only has access as defined in the Security Rules ref := client.NewRef("/some_resource") var data map[string]interface{} if err := ref.Get(ctx, &data); err != nil { log.Fatalln("Error reading from database:", err) } fmt.Println(data)
במקרים מסוימים, יכול להיות שתרצו לצמצם את ההיקף של ערכות ה-SDK לאדמינים כדי שהן יפעלו כלקוח לא מאומת. כדי לעשות זאת, צריך לספק ערך של null עבור שינוי משתנה האימות של מסד הנתונים.
Java
// Initialize the app with Application Default Credentials FirebaseOptions options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.getApplicationDefault()) // The database URL depends on the location of the database .setDatabaseUrl("https://DATABASE_NAME.firebaseio.com") .setDatabaseAuthVariableOverride(null) .build(); FirebaseApp.initializeApp(options); // The app only has access to public data as defined in the Security Rules DatabaseReference ref = FirebaseDatabase .getInstance() .getReference("/public_resource"); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { String res = dataSnapshot.getValue(); System.out.println(res); } });
Node.js
import { initializeApp } from 'firebase-admin/app'; import { getDatabase } from 'firebase-admin/database'; // Initialize the app with a null auth variable, limiting the server's access initializeApp({ // The database URL depends on the location of the database databaseURL: "https://DATABASE_NAME.firebaseio.com", databaseAuthVariableOverride: null }); // The app only has access to public data as defined in the Security Rules const db = getDatabase(); const ref = db.ref("/public_resource"); ref.once("value", (snapshot) => { console.log(snapshot.val()); });
Python
import firebase_admin from firebase_admin import credentials from firebase_admin import db # Fetch the service account key JSON file contents cred = credentials.Certificate('path/to/serviceAccountKey.json') # Initialize the app with a None auth variable, limiting the server's access firebase_admin.initialize_app(cred, { 'databaseURL': 'https://databaseName.firebaseio.com', 'databaseAuthVariableOverride': None }) # The app only has access to public data as defined in the Security Rules ref = db.reference('/public_resource') print(ref.get())
המשך
ctx := context.Background() // Initialize the app with a nil auth variable, limiting the server's access var nilMap map[string]interface{} conf := &firebase.Config{ DatabaseURL: "https://databaseName.firebaseio.com", AuthOverride: &nilMap, } // Fetch the service account key JSON file contents opt := option.WithCredentialsFile("path/to/serviceAccountKey.json") app, err := firebase.NewApp(ctx, conf, opt) if err != nil { log.Fatalln("Error initializing app:", err) } client, err := app.Database(ctx) if err != nil { log.Fatalln("Error initializing database client:", err) } // The app only has access to public data as defined in the Security Rules ref := client.NewRef("/some_resource") var data map[string]interface{} if err := ref.Get(ctx, &data); err != nil { log.Fatalln("Error reading from database:", err) } fmt.Println(data)