תכונות אימות מתקדמות

1. הגדרה

קבלת קוד המקור

בקודלאב הזה נתחיל מגרסה כמעט מלאה של אפליקציית הדוגמה Friendly Chat, ולכן הדבר הראשון שצריך לעשות הוא לשכפל את קוד המקור:

$ git clone https://github.com/firebase/codelab-friendlychat-web --branch security

לאחר מכן עוברים לספרייה security-start, שבה תפעלו במהלך שאר הקודלאב:

$ cd codelab-friendlychat-web/security-start

עכשיו צריך להתקין את יחסי התלות כדי שתוכלו להריץ את הקוד. אם החיבור לאינטרנט איטי, התהליך עשוי להימשך דקה או שתיים:

$ npm install && (cd functions && npm install)

מידע על המאגר הזה

הספרייה security-solution/ מכילה את הקוד המלא של האפליקציה לדוגמה. הספרייה security-start היא הספרייה שבה תלמדו את הקוד, וחסרים בה כמה חלקים חשובים של הטמעת האימות. הקבצים והתכונות העיקריים ב-security-start/ וב-security-solution/ הם:

  • functions/index.js מכיל קוד של Cloud Functions, ושם תכתבו פונקציות לחסימת אימות.
  • public/ – מכיל את הקבצים הסטטיים של אפליקציית הצ'אט
  • public/scripts/main.js – המקום שאליו מקמפלים את קוד ה-JS של אפליקציית הצ'אט (src/index.js)
  • src/firebase-config.js – מכיל את אובייקט התצורה של Firebase שמשמש לאינטליגנציה של אפליקציית הצ'אט
  • src/index.js – קוד ה-JS של אפליקציית הצ'אט

הורדת Firebase CLI

ערכת האמולטורים היא חלק מ-Firebase CLI (ממשק שורת הפקודה), שאפשר להתקין במחשב באמצעות הפקודה הבאה:

$ npm install -g firebase-tools@latest

יוצרים את קובץ ה-JavaScript באמצעות webpack, שיוצר את הקובץ main.js בתוך הספרייה public/scripts/.

webpack build

בשלב הבא, מוודאים שמשתמשים בגרסה האחרונה של CLI. סדנת הקוד הזו פועלת בגרסה 11.14 ואילך.

$ firebase --version
11.14.2

קישור לפרויקט Firebase

אם אין לכם פרויקט ב-Firebase, אתם יכולים ליצור פרויקט חדש ב-Firebase במסוף Firebase. חשוב לזכור את מזהה הפרויקט שבחרתם, כי תצטרכו אותו בהמשך.

עכשיו צריך לקשר את הקוד הזה לפרויקט Firebase. קודם כול, מריצים את הפקודה הבאה כדי להתחבר ל-CLI של Firebase:

$ firebase login

לאחר מכן, מריצים את הפקודה הבאה כדי ליצור כינוי לפרויקט. מחליפים את $YOUR_PROJECT_ID במזהה של פרויקט Firebase.

$ firebase use $YOUR_PROJECT_ID

עכשיו אפשר להריץ את האפליקציה.

2. הפעלת האמולטורים

בקטע הזה מריצים את האפליקציה באופן מקומי. זה אומר שהגיע הזמן להפעיל את Emulator Suite.

הפעלת המהדמנים

בתיקיית המקור של codelab, מריצים את הפקודה הבאה כדי להפעיל את המהדמנים:

$ firebase emulators:start

כך תוכלו להציג את האפליקציה בכתובת http://127.0.0.1:5170 ולבנות מחדש את קוד המקור בכל פעם שתבצעו שינויים. כדי לראות את השינויים, צריך רק לבצע רענון מלא (ctrl-shift-r) באופן מקומי בדפדפן.

הפלט אמור להיראות כך:

i  emulators: Starting emulators: auth, functions, firestore, hosting, storage
✔  functions: Using node@16 from host.
i  firestore: Firestore Emulator logging to firestore-debug.log
✔  firestore: Firestore Emulator UI websocket is running on 9150.
i  hosting[demo-example]: Serving hosting files from: ./public
✔  hosting[demo-example]: Local server: http://127.0.0.1:5170
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "[...]" for Cloud Functions...
✔  functions: Loaded functions definitions from source: beforecreated.
✔  functions[us-central1-beforecreated]: providers/cloud.auth/eventTypes/user.beforeCreate function initialized (http://127.0.0.1:5011/[...]/us-central1/beforecreated).
i  Running script: npm start
 
> security@1.0.0 start
> webpack --watch --progress
[...]
webpack 5.50.0 compiled with 1 warning in 990 ms

כשההודעה All emulators ready מופיעה, האפליקציה מוכנה לשימוש.

3. הטמעת אימות רב-שלבי

אימות דו-שלבי הוטמע באופן חלקי במאגר הזה. תצטרכו להוסיף את הקוד כדי לרשום משתמש לאימות דו-שלבי, ולאחר מכן כדי לבקש ממשתמשים שנרשמו לאימות דו-שלבי להזין גורם אימות שני.

פותחים את הקובץ src/index.js בכלי העריכה ומאתרים את השיטה startEnrollMultiFactor(). מוסיפים את הקוד הבא כדי להגדיר את מאמת reCAPTCHA שיימנע מניצול לרעה של הטלפון (מאמת reCAPTCHA מוגדר כ'נסתר' ולא יהיה גלוי למשתמשים):

async function startEnrollMultiFactor(phoneNumber) {
  const recaptchaVerifier = new RecaptchaVerifier(
    "recaptcha",
    { size: "invisible" },
    getAuth()
  );

לאחר מכן, מאתרים את השיטה finishEnrollMultiFactor() ומוסיפים את הפרטים הבאים כדי להירשם לשלב השני:

// Completes MFA enrollment once a verification code is obtained.
async function finishEnrollMultiFactor(verificationCode) {
  // Ask user for the verification code. Then:
  const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
  const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
 
  // Complete enrollment.
  await multiFactor(getAuth().currentUser)
    .enroll(multiFactorAssertion)
    .catch(function (error) {
      alert(`Error finishing second factor enrollment. ${error}`);
      throw error;
    });
  verificationId = null;
}

לאחר מכן, מחפשים את הפונקציה signIn ומוסיפים את תהליך הבקרה הבא, שמבקש ממשתמשים שנרשמו ל-MFA להזין את הגורם השני שלהם:

async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider)
    .then(function (userCredential) {
      // User successfully signed in and is not enrolled with a second factor.
    })
    .catch(function (error) {
      if (error.code == "auth/multi-factor-auth-required") {
        multiFactorResolver = getMultiFactorResolver(getAuth(), error);
        displaySecondFactor(multiFactorResolver.hints);
      } else {
        alert(`Error signing in user. ${error}`);
      }
    });
}

שאר ההטמעה, כולל הפונקציות שמופעלות כאן, כבר הושלמה. כדי לראות איך הם פועלים, אפשר לעיין בשאר הקובץ.

4. איך נכנסים באמצעות אימות דו-שלבי במהדמנים

עכשיו אפשר לנסות את ההטמעה של אימות ה-MFA. מוודאים שהמכונות הווירטואליות עדיין פועלות ונכנסים לאפליקציה שמתארחת באופן מקומי בכתובת localhost:5170. נסו להיכנס לחשבון. כשמתבקשים לספק את קוד האימות הדו-שלבי, הוא יופיע בחלון מסוף.

מאחר שהמעבדים התומכים תומכים באופן מלא באימות רב-גורמי, סביבת הפיתוח יכולה להיות עצמאית לחלוטין.

למידע נוסף על הטמעת אימות דו-שלבי, אפשר לעיין במסמכי העזרה שלנו.

5. יצירת פונקציית חסימה

יש אפליקציות שמיועדות לשימוש רק על ידי קבוצה ספציפית של משתמשים. במקרים כאלה, כדאי ליצור דרישות בהתאמה אישית כדי שמשתמשים יוכלו להירשם לאפליקציה או להיכנס אליה.

זה מה שאפשר לעשות באמצעות פונקציות חסימה: ליצור דרישות אימות בהתאמה אישית. הן פונקציות של Cloud Functions, אבל בניגוד לרוב הפונקציות, הן פועלות באופן סינכרוני כשמשתמש מנסה להירשם או להיכנס לחשבון.

כדי ליצור פונקציית חסימה, פותחים את functions/index.js בעורך ומאתרים את הפונקציה beforecreated עם ההערה.

מחליפים אותו בקוד הזה, שמאפשר רק למשתמשים עם דומיין example.com ליצור חשבון:

exports.beforecreated = beforeUserCreated((event) => {
  const user = event.data;
  // Only users of a specific domain can sign up.
  if (!user.email || !user.email.endsWith("@example.com")) {
    throw new HttpsError("invalid-argument", "Unauthorized email");
  }
});

6. איך בודקים את פונקציית החסימה במהדמנים

כדי לנסות את תכונת החסימה, מוודאים שהמכונות הווירטואליות פועלות, ובאפליקציית האינטרנט בכתובת localhost:5170 יוצאים מהחשבון.

לאחר מכן, מנסים ליצור חשבון עם כתובת אימייל שלא מסתיימת ב-example.com. פונקציית החסימה תמנע את השלמת הפעולה.

עכשיו צריך לנסות שוב עם כתובת אימייל שמסתיימת ב-example.com. החשבון נוצר בהצלחה.

פונקציות חסימה מאפשרות ליצור את כל ההגבלות הנדרשות לגבי אימות. מידע נוסף זמין במאמרי העזרה.

סיכום

מצוין! הוספתם אימות רב-שלבי לאפליקציית אינטרנט כדי לעזור למשתמשים לשמור על אבטחת החשבון שלהם, ואז יצרתם דרישות מותאמות אישית כדי שהמשתמשים יוכלו להירשם באמצעות פונקציות חסימה. בהחלט מגיע לך GIF!

קובץ GIF של אנשים מהמשרד שרקדו את ריקוד 'הרים את הגג'