Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

אמת באמצעות Firebase באמצעות קישור דוא"ל ב- JavaScript

תוכל להשתמש באימות Firebase כדי להיכנס למשתמש על ידי שליחת הודעת דואר אלקטרוני המכילה קישור שאליו הוא יכול ללחוץ כדי להיכנס. תוך כדי כך גם כתובת הדוא"ל של המשתמש מאומתת.

יש הרבה יתרונות בכניסה למייל:

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

לפני שאתה מתחיל

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

כדי להיכנס למשתמשים באמצעות קישור דוא"ל, תחילה עליך להפעיל את ספק הדוא"ל ואת שיטת הכניסה לקישור הדוא"ל עבור פרויקט Firebase שלך:

  1. בשנות ה קונסולת Firebase , פתח את הקטע המחבר.
  2. 'הכניסה דרך כרטיסיית שיטה, לאפשר ספקית האימייל / סיסמה. שים לב כי יש להפעיל כניסה לדוא"ל/סיסמה כדי להשתמש בכניסה לקישור דוא"ל.
  3. באותו הסעיף, לאפשר קישור דוא"ל (passwordless כניסה) כניסת שיטה.
  4. לחץ על שמור.

כדי ליזום את זרימת אימות, להציג למשתמש עם ממשק המודיע למשתמש לספק את כתובת האימייל שלהם ואז להתקשר sendSignInLinkToEmail לבקשה כי Firebase לשלוח את הקישור אימות הדוא"ל של המשתמש.

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

    • url : הקישור העמוק אל שבץ וכל מדינה נוספת יועברו יחד. יש להוסיף את הדומיין של הקישור ברשימת הדומיינים המורשים של Firebase Console, שניתן למצוא אותו בכרטיסייה שיטת כניסה (אימות-> שיטת כניסה).
    • android ו- ios : היישומים להשתמש כאשר הכניסה הקישור נפתח על מכשיר אנדרואיד או iOS. למידע נוסף על איך להגדיר Firebase דינמי קישורים לקישורי פעולת דוא"ל פתוח באמצעות יישומים ניידים.
    • handleCodeInApp : הגדר האמיתי. תמיד יש להשלים את פעולת הכניסה באפליקציה בניגוד לפעולות דוא"ל מחוץ ללהקה (איפוס סיסמה ואימות דוא"ל). הסיבה לכך היא שבסוף הזרימה המשתמש צפוי להיכנס למערכת ומצב האימות שלו נמשך בתוך האפליקציה.
    • dynamicLinkDomain : כאשר תחומים דינמי קישור מותאם אישית מרובים מוגדרים עבור פרויקט, לציין איזה מהם להשתמש כאשר הקישור הוא להיפתח באמצעות יישום נייד מצוין (למשל, example.page.link ). אחרת הדומיין הראשון ייבחר באופן אוטומטי.

      גרסת אינטרנט 9

      const actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        dynamicLinkDomain: 'example.page.link'
      };

      גרסת אינטרנט 8

      var actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        dynamicLinkDomain: 'example.page.link'
      };

    כדי ללמוד עוד על ActionCodeSettings, עיינו המדינה עוברת בפעולות דוא"ל סעיף.

  2. בקש מהמשתמש את הדוא"ל שלו.

  3. שלח את קישור האימות לדוא"ל המשתמש, ושמור את הודעת הדוא"ל של המשתמש במקרה שהמשתמש ישלים את הכניסה לדוא"ל באותו מכשיר.

    גרסת אינטרנט 9

    import { getAuth, sendSignInLinkToEmail } from "firebase/auth";
    
    const auth = getAuth();
    sendSignInLinkToEmail(auth, email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        // ...
      });

    גרסת אינטרנט 8

    firebase.auth().sendSignInLinkToEmail(email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        var errorCode = error.code;
        var errorMessage = error.message;
        // ...
      });

חששות אבטחה

כדי למנוע שימוש בקישור כניסה כדי להיכנס כמשתמש לא מכוון או במכשיר לא מכוון, Firebase Auth דורש לספק את כתובת הדוא"ל של המשתמש בעת השלמת זרימת הכניסה. כדי שהכניסה תצליח, כתובת דוא"ל זו חייבת להתאים לכתובת שאליה נשלח במקור קישור הכניסה.

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

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

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

השלמת כניסה לדף אינטרנט

הפורמט של הקישור העמוק קישור הדוא"ל הוא זהה בפורמט המשמש את הפעולות הדוא"ל הלהקה (אימות הדוא"ל, לאפס את הסיסמה ואת ביטול שינוי אימייל). מחבר Firebase מפשט לבדוק זאת על ידי מתן isSignInWithEmailLink API כדי לבדוק אם קישור הוא סימן-ב עם קישור בדוא"ל.

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

גרסת אינטרנט 9

import { getAuth, isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth";

// Confirm the link is a sign-in with email link.
const auth = getAuth();
if (isSignInWithEmailLink(auth, window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  let email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  signInWithEmailLink(auth, email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user via result.user
      // Additional user info profile not available via:
      // result.additionalUserInfo.profile == null
      // You can check if the user is new or existing:
      // result.additionalUserInfo.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

גרסת אינטרנט 8

// Confirm the link is a sign-in with email link.
if (firebase.auth().isSignInWithEmailLink(window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  var email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  firebase.auth().signInWithEmailLink(email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user via result.user
      // Additional user info profile not available via:
      // result.additionalUserInfo.profile == null
      // You can check if the user is new or existing:
      // result.additionalUserInfo.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

השלמת כניסה באפליקציה לנייד

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

כדי ללמוד עוד על איך להתמודד עם הכניסה עם קישור בדוא"ל ביישום Android, עיינו במדריך אנדרואיד .

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

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

ההבדל יהיה במחצית השנייה של הפעולה:

גרסת אינטרנט 9

import { getAuth, linkWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
const auth = getAuth();
linkWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

גרסת אינטרנט 8

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
firebase.auth().currentUser.linkWithCredential(credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

ניתן להשתמש בזה גם לאימות מחדש של משתמש בקישור דוא"ל לפני הפעלת פעולה רגישה.

גרסת אינטרנט 9

import { getAuth, reauthenticateWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
const auth = getAuth();
reauthenticateWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

גרסת אינטרנט 8

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
firebase.auth().currentUser.reauthenticateWithCredential(credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

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

במקרה אתה תומך בשני סיסמה בקישור מבוסס כניסה עם הדוא"ל, להבדיל שיטת הכניסה עבור משתמש וסיסמה / link, להשתמש fetchSignInMethodsForEmail . זה שימושי עבור זרימות קודמות לזהות שבהן המשתמש מתבקש לראשונה לספק את הדוא"ל שלו ולאחר מכן מוצגת לו שיטת הכניסה:

גרסת אינטרנט 9

import { getAuth, fetchSignInMethodsForEmail, EmailAuthProvider} from "firebase/auth";

// After asking the user for their email.
const email = window.prompt('Please provide your email');

const auth = getAuth();
fetchSignInMethodsForEmail(auth, email)
  .then((signInMethods) => {
    // This returns the same array as fetchProvidersForEmail but for email
    // provider identified by 'password' string, signInMethods would contain 2
    // different strings:
    // 'emailLink' if the user previously signed in with an email/link
    // 'password' if the user has a password.
    // A user could have both.
    if (signInMethods.indexOf(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/password.
    }
    if (signInMethods.indexOf(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/link.
    }
  })
  .catch((error) => {
    // Some error occurred, you can inspect the code: error.code
  });

גרסת אינטרנט 8

// After asking the user for their email.
var email = window.prompt('Please provide your email');
firebase.auth().fetchSignInMethodsForEmail(email)
  .then((signInMethods) => {
    // This returns the same array as fetchProvidersForEmail but for email
    // provider identified by 'password' string, signInMethods would contain 2
    // different strings:
    // 'emailLink' if the user previously signed in with an email/link
    // 'password' if the user has a password.
    // A user could have both.
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/password.
    }
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/link.
    }
  })
  .catch((error) => {
    // Some error occurred, you can inspect the code: error.code
  });

כפי שתואר לעיל הדוא"ל / סיסמא ודואר אלקטרוני / link נחשב באותה firebase.auth.EmailAuthProvider (באותו PROVIDER_ID ) עם שיטות שונות של כניסה.

הצעדים הבאים

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

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

  • בבסיס הנתונים בזמן אמת Firebase שלך לאחסון בענן אבטחה חוקי , אתה יכול לקבל את שנכנסים למערכת זיהוי המשתמש הייחודי של המשתמש מן auth משתנה, ולהשתמש בו כדי לקבוע אילו נתונים גישה יכול משתמש.

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

כדי לצאת מהחשבון משתמש, קוראים signOut :

גרסת אינטרנט 9

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

גרסת אינטרנט 8

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});