יצירת רכיבי handler מותאמים אישית לפעולות באימייל

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

במקום זאת, אפשר ליצור ולארח handler של פעולות בהתאמה אישית לאימייל כדי לבצע פעולות בהתאמה אישית ולשלב את ה-handler של פעולות האימייל באתר שלכם.

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

  • איפוס הסיסמאות
  • ביטול שינויים בכתובת האימייל - כאשר משתמשים משנים את חשבון ראשית כתובות אימייל, מערכת Firebase שולחת הודעת אימייל לכתובות הישנות שלה שמאפשרות כדי לבטל את השינוי
  • אימות כתובות אימייל

כדי להתאים אישית את הטיפול בפעולות אימייל בפרויקט Firebase, צריך ליצור ולתת אירוח לדף אינטרנט שמשתמש ב-Firebase JavaScript SDK כדי לאמת את תקינות הבקשה ולהשלים אותה. לאחר מכן צריך להתאים אישית את Firebase תבניות האימייל של הפרויקט כדי לקשר ל-handler של הפעולות המותאמות אישית.

יצירת הדף לטיפול בפעולות באימייל

  1. מערכת Firebase מוסיפה כמה פרמטרים של שאילתות לכתובת ה-URL של פונקציית הטיפול בפעולה כשהיא יוצרת אימיילים לניהול משתמשים. לדוגמה:

    https://example.com/usermgmt?mode=resetPassword&oobCode=ABC123&apiKey=AIzaSy...&lang=fr

    הפרמטרים האלה מציינים את המשימה של ניהול המשתמשים שהמשתמש מבצע. דף ה-handler של הפעולות באימייל חייב לטפל בשאילתה הבאה :

    פרמטרים
    מצב

    פעולת ניהול המשתמשים שצריך להשלים. הערך יכול להיות אחד מהערכים הבאים:

    • resetPassword
    • recoverEmail
    • verifyEmail
    oobCode קוד חד-פעמי המשמש לזיהוי ולאימות של בקשה
    apiKey מפתח ה-API של פרויקט Firebase, למען הנוחות
    כתובת URL להמשך זוהי כתובת URL אופציונלית שמאפשרת להעביר את המצב חזרה לאפליקציה דרך כתובת URL. זה רלוונטי לאיפוס סיסמה ולשליחת אימייל מצבי האימות. כדי שאפשר יהיה לשלוח אימייל לאיפוס הסיסמה או אימייל לאימות, צריך לציין אובייקט ActionCodeSettings עם כתובת URL להמשך. הזה מאפשרת למשתמש להמשיך ישר מהנקודה שבה הפסיק בעקבות פעולה שביצעתם באימייל.
    lang

    זהו תג השפה האופציונלי של BCP47 שמייצג את האזור הגיאוגרפי והשפה של המשתמש (לדוגמה, fr). אפשר להשתמש בערך הזה כדי לספק למשתמשים דפי טיפול בפעולות באימייל שמותאמים לשפה שלהם.

    אפשר להגדיר את ההתאמה אישית למקום דרך מסוף Firebase או באופן דינמי על ידי קריאה לממשק ה-API המתאים של הלקוח לפני הפעלת הפעולה של שליחת האימייל. לדוגמה, באמצעות JavaScript: firebase.auth().languageCode = 'fr';

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

    בדוגמה הבאה אפשר לראות איך אפשר לטפל בפרמטרים של השאילתה ב-handler מבוסס-דפדפן. (אפשר גם להטמיע את הטיפול כאפליקציית Node.js באמצעות לוגיקה דומה).

    Web

    import { initializeApp } from "firebase/app";
    import { getAuth } from "firebase/auth";
    
    document.addEventListener('DOMContentLoaded', () => {
      // TODO: Implement getParameterByName()
    
      // Get the action to complete.
      const mode = getParameterByName('mode');
      // Get the one-time code from the query parameter.
      const actionCode = getParameterByName('oobCode');
      // (Optional) Get the continue URL from the query parameter if available.
      const continueUrl = getParameterByName('continueUrl');
      // (Optional) Get the language code if available.
      const lang = getParameterByName('lang') || 'en';
    
      // Configure the Firebase SDK.
      // This is the minimum configuration required for the API to be used.
      const config = {
        'apiKey': "YOUR_API_KEY" // Copy this key from the web initialization
                                 // snippet found in the Firebase console.
      };
      const app = initializeApp(config);
      const auth = getAuth(app);
    
      // Handle the user management action.
      switch (mode) {
        case 'resetPassword':
          // Display reset password handler and UI.
          handleResetPassword(auth, actionCode, continueUrl, lang);
          break;
        case 'recoverEmail':
          // Display email recovery handler and UI.
          handleRecoverEmail(auth, actionCode, lang);
          break;
        case 'verifyEmail':
          // Display email verification handler and UI.
          handleVerifyEmail(auth, actionCode, continueUrl, lang);
          break;
        default:
          // Error: invalid mode.
      }
    }, false);

    Web

    document.addEventListener('DOMContentLoaded', () => {
      // TODO: Implement getParameterByName()
    
      // Get the action to complete.
      var mode = getParameterByName('mode');
      // Get the one-time code from the query parameter.
      var actionCode = getParameterByName('oobCode');
      // (Optional) Get the continue URL from the query parameter if available.
      var continueUrl = getParameterByName('continueUrl');
      // (Optional) Get the language code if available.
      var lang = getParameterByName('lang') || 'en';
    
      // Configure the Firebase SDK.
      // This is the minimum configuration required for the API to be used.
      var config = {
        'apiKey': "YOU_API_KEY" // Copy this key from the web initialization
                                // snippet found in the Firebase console.
      };
      var app = firebase.initializeApp(config);
      var auth = app.auth();
    
      // Handle the user management action.
      switch (mode) {
        case 'resetPassword':
          // Display reset password handler and UI.
          handleResetPassword(auth, actionCode, continueUrl, lang);
          break;
        case 'recoverEmail':
          // Display email recovery handler and UI.
          handleRecoverEmail(auth, actionCode, lang);
          break;
        case 'verifyEmail':
          // Display email verification handler and UI.
          handleVerifyEmail(auth, actionCode, continueUrl, lang);
          break;
        default:
          // Error: invalid mode.
      }
    }, false);
  2. כדי לטפל בבקשות לאיפוס סיסמה, קודם מאמתים את קוד הפעולה באמצעות verifyPasswordResetCode, ואז מקבלים מהמשתמש סיסמה חדשה ומעבירים אותה אל confirmPasswordReset. לדוגמה:

    Web

    import { verifyPasswordResetCode, confirmPasswordReset } from "firebase/auth";
    
    function handleResetPassword(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
    
      // Verify the password reset code is valid.
      verifyPasswordResetCode(auth, actionCode).then((email) => {
        const accountEmail = email;
    
        // TODO: Show the reset screen with the user's email and ask the user for
        // the new password.
        const newPassword = "...";
    
        // Save the new password.
        confirmPasswordReset(auth, actionCode, newPassword).then((resp) => {
          // Password reset has been confirmed and new password updated.
    
          // TODO: Display a link back to the app, or sign-in the user directly
          // if the page belongs to the same domain as the app:
          // auth.signInWithEmailAndPassword(accountEmail, newPassword);
    
          // TODO: If a continue URL is available, display a button which on
          // click redirects the user back to the app via continueUrl with
          // additional state determined from that URL's parameters.
        }).catch((error) => {
          // Error occurred during confirmation. The code might have expired or the
          // password is too weak.
        });
      }).catch((error) => {
        // Invalid or expired action code. Ask user to try to reset the password
        // again.
      });
    }

    Web

    function handleResetPassword(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
    
      // Verify the password reset code is valid.
      auth.verifyPasswordResetCode(actionCode).then((email) => {
        var accountEmail = email;
    
        // TODO: Show the reset screen with the user's email and ask the user for
        // the new password.
        var newPassword = "...";
    
        // Save the new password.
        auth.confirmPasswordReset(actionCode, newPassword).then((resp) => {
          // Password reset has been confirmed and new password updated.
    
          // TODO: Display a link back to the app, or sign-in the user directly
          // if the page belongs to the same domain as the app:
          // auth.signInWithEmailAndPassword(accountEmail, newPassword);
    
          // TODO: If a continue URL is available, display a button which on
          // click redirects the user back to the app via continueUrl with
          // additional state determined from that URL's parameters.
        }).catch((error) => {
          // Error occurred during confirmation. The code might have expired or the
          // password is too weak.
        });
      }).catch((error) => {
        // Invalid or expired action code. Ask user to try to reset the password
        // again.
      });
    }
  3. כדי לטפל בביטולים של שינויים בכתובת האימייל, קודם כול צריך לאמת את קוד הפעולה עם checkActionCode; ואז משחזרים את כתובת האימייל של המשתמש עם applyActionCode. לדוגמה:

    Web

    import { checkActionCode, applyActionCode, sendPasswordResetEmail } from "firebase/auth";
    
    function handleRecoverEmail(auth, actionCode, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      let restoredEmail = null;
      // Confirm the action code is valid.
      checkActionCode(auth, actionCode).then((info) => {
        // Get the restored email address.
        restoredEmail = info['data']['email'];
    
        // Revert to the old email.
        return applyActionCode(auth, actionCode);
      }).then(() => {
        // Account email reverted to restoredEmail
    
        // TODO: Display a confirmation message to the user.
    
        // You might also want to give the user the option to reset their password
        // in case the account was compromised:
        sendPasswordResetEmail(auth, restoredEmail).then(() => {
          // Password reset confirmation sent. Ask user to check their email.
        }).catch((error) => {
          // Error encountered while sending password reset code.
        });
      }).catch((error) => {
        // Invalid code.
      });
    }

    Web

    function handleRecoverEmail(auth, actionCode, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      var restoredEmail = null;
      // Confirm the action code is valid.
      auth.checkActionCode(actionCode).then((info) => {
        // Get the restored email address.
        restoredEmail = info['data']['email'];
    
        // Revert to the old email.
        return auth.applyActionCode(actionCode);
      }).then(() => {
        // Account email reverted to restoredEmail
    
        // TODO: Display a confirmation message to the user.
    
        // You might also want to give the user the option to reset their password
        // in case the account was compromised:
        auth.sendPasswordResetEmail(restoredEmail).then(() => {
          // Password reset confirmation sent. Ask user to check their email.
        }).catch((error) => {
          // Error encountered while sending password reset code.
        });
      }).catch((error) => {
        // Invalid code.
      });
    }
  4. לטפל באימות כתובת האימייל באמצעות שיחה למספר applyActionCode. לדוגמה:

    Web

    function handleVerifyEmail(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      // Try to apply the email verification code.
      applyActionCode(auth, actionCode).then((resp) => {
        // Email address has been verified.
    
        // TODO: Display a confirmation message to the user.
        // You could also provide the user with a link back to the app.
    
        // TODO: If a continue URL is available, display a button which on
        // click redirects the user back to the app via continueUrl with
        // additional state determined from that URL's parameters.
      }).catch((error) => {
        // Code is invalid or expired. Ask the user to verify their email address
        // again.
      });
    }

    Web

    function handleVerifyEmail(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      // Try to apply the email verification code.
      auth.applyActionCode(actionCode).then((resp) => {
        // Email address has been verified.
    
        // TODO: Display a confirmation message to the user.
        // You could also provide the user with a link back to the app.
    
        // TODO: If a continue URL is available, display a button which on
        // click redirects the user back to the app via continueUrl with
        // additional state determined from that URL's parameters.
      }).catch((error) => {
        // Code is invalid or expired. Ask the user to verify their email address
        // again.
      });
    }
  5. מארחים את הדף במקום כלשהו, למשל Firebase Hosting.

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

כדי להגדיר את פרויקט Firebase כך שישתמש במטפל הפעולות המותאם אישית של האימייל:

  1. פותחים את הפרויקט במסוף Firebase.
  2. עוברים לדף Email Templates בקטע Auth.
  3. בכל אחת מהרשומות של סוגי אימייל, לוחצים על סמל העיפרון כדי לערוך את תבנית אימייל.
  4. לוחצים על Customize action URL (התאמה אישית של כתובת URL לפעולה) ומציינים את כתובת ה-URL של כתובת האימייל המותאמת אישית שמטפל בפעולות.

אחרי שתשמרו את כתובת ה-URL, היא תשמש בכל כתובות האימייל של פרויקט Firebase שלכם תבניות.