אימות משתמשים באמצעות Firebase

מזהה אזור

REGION_ID הוא קוד מקוצר ש-Google מקצה על סמך האזור שבוחרים כשיוצרים את האפליקציה. הקוד לא תואם למדינה או למחוז, למרות שחלק ממזהי האזורים עשויים להיראות דומים לקודים נפוצים של מדינות ומחוזות. באפליקציות שנוצרו אחרי פברואר 2020, REGION_ID.r נכלל בכתובות URL של App Engine. באפליקציות קיימות שנוצרו לפני התאריך הזה, מזהה האזור הוא אופציונלי בכתובת ה-URL.

מידע נוסף על מזהי אזורים

מוסיפים לשירות האינטרנט תהליך כניסה למשתמשים שמשתמש באימות ב-Firebase.

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

לפני שמתחילים

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

הוספת שיטות אימות של Firebase

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

כדי להוסיף את ההתנהגויות הנדרשות לתהליך אימות, מחליפים את שיטת event listener הנוכחית בקובץ static/script.js בקוד הבא:

window.addEventListener('load', function () {
  document.getElementById('sign-out').onclick = function () {
    firebase.auth().signOut();
  };

  // FirebaseUI config.
  var uiConfig = {
    signInSuccessUrl: '/',
    signInOptions: [
      // Comment out any lines corresponding to providers you did not check in
      // the Firebase console.
      firebase.auth.GoogleAuthProvider.PROVIDER_ID,
      firebase.auth.EmailAuthProvider.PROVIDER_ID,
      //firebase.auth.FacebookAuthProvider.PROVIDER_ID,
      //firebase.auth.TwitterAuthProvider.PROVIDER_ID,
      //firebase.auth.GithubAuthProvider.PROVIDER_ID,
      //firebase.auth.PhoneAuthProvider.PROVIDER_ID

    ],
    // Terms of service url.
    tosUrl: '<your-tos-url>'
  };

  firebase.auth().onAuthStateChanged(function (user) {
    if (user) {
      // User is signed in, so display the "sign out" button and login info.
      document.getElementById('sign-out').hidden = false;
      document.getElementById('login-info').hidden = false;
      console.log(`Signed in as ${user.displayName} (${user.email})`);
      user.getIdToken().then(function (token) {
        // Add the token to the browser's cookies. The server will then be
        // able to verify the token against the API.
        // SECURITY NOTE: As cookies can easily be modified, only put the
        // token (which is verified server-side) in a cookie; do not add other
        // user information.
        document.cookie = "token=" + token;
      });
    } else {
      // User is signed out.
      // Initialize the FirebaseUI Widget using Firebase.
      var ui = new firebaseui.auth.AuthUI(firebase.auth());
      // Show the Firebase login button.
      ui.start('#firebaseui-auth-container', uiConfig);
      // Update the login state indicators.
      document.getElementById('sign-out').hidden = true;
      document.getElementById('login-info').hidden = true;
      // Clear the token cookie.
      document.cookie = "token=";
    }
  }, function (error) {
    console.log(error);
    alert('Unable to log in: ' + error)
  });
});

שימו לב שהשיטה onAuthStateChanged(), שקובעת אילו שינויים יתרחשו כשמשתמש מתחבר או מתנתק, שומרת את אסימון המזהה של המשתמש כקובץ Cookie. טוקן המזהה הזה הוא טוקן ייחודי שנוצר אוטומטית על ידי Firebase כשמשתמש נכנס בהצלחה לחשבון, והוא משמש את השרת לאימות המשתמש.

עדכון שירות האינטרנט לשימוש באסימונים

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

כדי להשתמש באסימון המזהה של Firebase:

  1. מאחזרים, מאמתים ומפענחים את האסימון בשיטה root בקובץ: main.py

    from flask import Flask, render_template, request
    from google.auth.transport import requests
    from google.cloud import datastore
    import google.oauth2.id_token
    
    firebase_request_adapter = requests.Request()
    @app.route("/")
    def root():
        # Verify Firebase auth.
        id_token = request.cookies.get("token")
        error_message = None
        claims = None
        times = None
    
        if id_token:
            try:
                # Verify the token against the Firebase Auth API. This example
                # verifies the token on each page load. For improved performance,
                # some applications may wish to cache results in an encrypted
                # session store (see for instance
                # http://flask.pocoo.org/docs/1.0/quickstart/#sessions).
                claims = google.oauth2.id_token.verify_firebase_token(
                    id_token, firebase_request_adapter
                )
            except ValueError as exc:
                # This will be raised if the token is expired or any other
                # verification checks fail.
                error_message = str(exc)
    
            # Record and fetch the recent times a logged-in user has accessed
            # the site. This is currently shared amongst all users, but will be
            # individualized in a following step.
            store_time(datetime.datetime.now(tz=datetime.timezone.utc))
            times = fetch_times(10)
    
        return render_template(
            "index.html", user_data=claims, error_message=error_message, times=times
        )
    
    
  2. מוודאים שקובץ ה-requirements.txt כולל את כל התלויות הנדרשות:

    Flask==3.0.0
    google-cloud-datastore==2.15.1
    google-auth==2.17.3
    requests==2.28.2
    

בדיקת שירות האינטרנט

בודקים את שירות האינטרנט על ידי הפעלתו באופן מקומי בסביבה וירטואלית:

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

    pip install -r requirements.txt
    python main.py
    
  2. כדי לראות את שירות האינטרנט, מזינים את הכתובת הבאה בדפדפן האינטרנט:

    http://localhost:8080
    

פריסת שירות האינטרנט

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

מריצים את הפקודה הבאה מתיקיית הרמה הבסיסית (root) של הפרויקט, שבה נמצא הקובץ app.yaml:

gcloud app deploy

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

מידע נוסף על ניהול גרסאות זמין במאמר ניהול שירותים וגרסאות.

צפייה בשירות

כדי להפעיל במהירות את הדפדפן ולגשת לשירות האינטרנט בכתובת https://PROJECT_ID.REGION_ID.r.appspot.com, מריצים את הפקודה הבאה:

gcloud app browse

השלבים הבאים

אחרי שהגדרתם אימות משתמשים, אתם יכולים לעדכן את שירות האינטרנט כדי להתאים אישית את הנתונים למשתמשים מאומתים.