Łatwe logowanie się w aplikacji internetowej dzięki FirebaseUI

FirebaseUI to biblioteka utworzona na podstawie pakietu SDK Uwierzytelniania Firebase, która udostępnia gotowe przepływy interfejsu użytkownika do użycia w aplikacji. FirebaseUI zapewnia następujące korzyści:

  • Wielu dostawców – sposoby logowania się w przypadku adresu e-mail/hasło, linku w e-mailu, uwierzytelniania telefonicznego, logowania w Google, na Facebooku, Twitterze i w GitHubie.
  • Łączenie kont – umożliwia bezpieczne łączenie kont użytkowników u różnych dostawców tożsamości.
  • Dostosowanie – zastąp style CSS interfejsu FirebaseUI, aby dopasować je do wymagań aplikacji. Oprócz tego FirebaseUI to oprogramowanie typu open source, co oznacza, że projekt można utworzyć na rozwidleniu i dostosować do własnych potrzeb.
  • Rejestracja jednym kliknięciem i logowanie automatyczne – automatyczna integracja z rejestracją jednym dotknięciem, która umożliwia szybkie logowanie się na różnych urządzeniach.
  • Zlokalizowany interfejs użytkownika – internacjonalizacja ponad 40 języków.
  • Uaktualnianie użytkowników anonimowych – możliwość uaktualniania anonimowych użytkowników przez logowanie lub rejestrację. Więcej informacji znajdziesz w sekcji Uaktualnianie anonimowych użytkowników.

Zanim zaczniesz

  1. Dodaj Uwierzytelnianie Firebase do swojej aplikacji internetowej, upewniając się, że używasz pakietu SDK w wersji 9 (zalecane) lub starszej (patrz pasek boczny powyżej).

  2. Uwzględnij FirebaseUI, korzystając z jednej z tych opcji:

    1. CDN

      Umieść ten skrypt i plik CSS w tagu <head> strony, pod fragmentem kodu inicjującym z konsoli Firebase:

      <script src="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.js"></script>
      <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.css" />
      
    2. Moduł npm

      Zainstaluj FirebaseUI i jego zależności przez npm, używając tego polecenia:

      $ npm install firebaseui --save
      

      require te moduły w plikach źródłowych:

      var firebase = require('firebase');
      var firebaseui = require('firebaseui');
      
    3. Komponent łuku

      Zainstaluj FirebaseUI i jej zależności przez Bower, korzystając z następującego polecenia:

      $ bower install firebaseui --save
      

      Jeśli serwer HTTP obsługuje pliki w obrębie bower_components/, uwzględnij wymagane pliki w kodzie HTML:

      <script src="bower_components/firebaseui/dist/firebaseui.js"></script>
      <link type="text/css" rel="stylesheet" href="bower_components/firebaseui/dist/firebaseui.css" />
      

Zainicjuj FirebaseUI

Po zaimportowaniu pakietu SDK zainicjuj interfejs uwierzytelniania.

// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());

Skonfiguruj metody logowania

Aby móc logować użytkowników za pomocą Firebase, musisz włączyć i skonfigurować metody logowania, które mają być obsługiwane.

Adres e-mail i hasło

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie i włącz uwierzytelnianie za pomocą adresu e-mail oraz hasła.

  2. Dodaj identyfikator dostawcy poczty e-mail do listy FirebaseUI signInOptions.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        firebase.auth.EmailAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  3. Opcjonalnie: element EmailAuthProvider można skonfigurować tak, aby wymagał od użytkownika wpisania wyświetlanej nazwy (domyślnie true).

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
          requireDisplayName: false
        }
      ]
    });
    
  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie. Na karcie Metoda logowania włącz dostawcę E-mail/hasło. Pamiętaj, że aby korzystać z logowania za pomocą linku e-mail, musisz włączyć logowanie za pomocą adresu e-mail i hasła.

  2. W tej samej sekcji włącz metodę logowania Link w e-mailu (logowanie bez hasła) i kliknij Zapisz.

  3. Dodaj identyfikator dostawcy poczty e-mail do listy interfejsu FirebaseUI signInOptions wraz z linkiem do e-maila signInMethod.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
          signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD
        }
      ],
      // Other config options...
    });
    
  4. Gdy renderujesz interfejs logowania warunkowo (dotyczy aplikacji jednostronicowych), użyj parametru ui.isPendingRedirect(), aby wykryć, czy adres URL odpowiada linkowi logowania z linkiem w e-mailu. Aby można było się zalogować, interfejs musi zostać wyrenderowany.

    // Is there an email link sign-in?
    if (ui.isPendingRedirect()) {
      ui.start('#firebaseui-auth-container', uiConfig);
    }
    // This can also be done via:
    if (firebase.auth().isSignInWithEmailLink(window.location.href)) {
      ui.start('#firebaseui-auth-container', uiConfig);
    }
    
  5. Opcjonalnie: możesz skonfigurować ustawienia EmailAuthProvider w przypadku logowania się za pomocą linku w e-mailu, aby zezwolić użytkownikowi na logowanie się na różnych urządzeniach lub go zablokować.

    Można zdefiniować opcjonalne wywołanie zwrotne emailLinkSignIn, które zwraca konfigurację firebase.auth.ActionCodeSettings używaną przy wysyłaniu linku. Pozwala to określić sposób obsługi linku, niestandardowy link dynamiczny, dodatkowy stan precyzyjnego linku itd. Jeśli nie zostanie podany, używany będzie bieżący adres URL, co spowoduje uruchomienie przepływu tylko internetowego.

    Logowanie za pomocą linku e-mail w FirebaseUI-web jest zgodne z FirebaseUI-Android i FirebaseUI-iOS. W tym przypadku użytkownik rozpoczynający proces z FirebaseUI-Android może otworzyć ten link i zalogować się przez FirebaseUI-web. To samo dotyczy przeciwnego przepływu.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
          signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD,
          // Allow the user the ability to complete sign-in cross device,
          // including the mobile apps specified in the ActionCodeSettings
          // object below.
          forceSameDevice: false,
          // Used to define the optional firebase.auth.ActionCodeSettings if
          // additional state needs to be passed along request and whether to open
          // the link in a mobile app if it is installed.
          emailLinkSignIn: function() {
            return {
              // Additional state showPromo=1234 can be retrieved from URL on
              // sign-in completion in signInSuccess callback by checking
              // window.location.href.
              url: 'https://www.example.com/completeSignIn?showPromo=1234',
              // Custom FDL domain.
              dynamicLinkDomain: 'example.page.link',
              // Always true for email link sign-in.
              handleCodeInApp: true,
              // Whether to handle link in iOS app if installed.
              iOS: {
                bundleId: 'com.example.ios'
              },
              // Whether to handle link in Android app if opened in an Android
              // device.
              android: {
                packageName: 'com.example.android',
                installApp: true,
                minimumVersion: '12'
              }
            };
          }
        }
      ]
    });
    

Dostawcy protokołu OAuth (Google, Facebook, Twitter i GitHub)

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie i włącz logowanie przez określonego dostawcę protokołu OAuth. Upewnij się, że podano też odpowiedni identyfikator klienta i tajny klucz OAuth.

  2. Poza tym w sekcji Uwierzytelnianie upewnij się, że domena, w której będzie renderowana strona logowania, również została dodana do listy autoryzowanych domen.

  3. Dodaj identyfikator dostawcy OAuth do listy interfejsu FirebaseUI signInOptions.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        // List of OAuth providers supported.
        firebase.auth.GoogleAuthProvider.PROVIDER_ID,
        firebase.auth.FacebookAuthProvider.PROVIDER_ID,
        firebase.auth.TwitterAuthProvider.PROVIDER_ID,
        firebase.auth.GithubAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  4. Opcjonalnie: aby określić niestandardowe zakresy lub niestandardowe parametry OAuth dla każdego dostawcy, możesz przekazać obiekt, a nie samą wartość dostawcy:

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
          scopes: [
            'https://www.googleapis.com/auth/contacts.readonly'
          ],
          customParameters: {
            // Forces account selection even when one account
            // is available.
            prompt: 'select_account'
          }
        },
        {
          provider: firebase.auth.FacebookAuthProvider.PROVIDER_ID,
          scopes: [
            'public_profile',
            'email',
            'user_likes',
            'user_friends'
          ],
          customParameters: {
            // Forces password re-entry.
            auth_type: 'reauthenticate'
          }
        },
        firebase.auth.TwitterAuthProvider.PROVIDER_ID, // Twitter does not support scopes.
        firebase.auth.EmailAuthProvider.PROVIDER_ID // Other providers don't need to be given as object.
      ]
    });
    

Numer telefonu

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie i włącz logowanie przy użyciu numeru telefonu.

  2. Upewnij się, że domena, w której będzie renderowana strona logowania, została również dodana do listy autoryzowanych domen.

  3. Dodaj identyfikator dostawcy numeru telefonu do listy FirebaseUI signInOptions.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        firebase.auth.PhoneAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  4. Opcjonalnie: obiekt PhoneAuthProvider można skonfigurować za pomocą niestandardowych parametrów reCAPTCHA niezależnie od tego, czy reCAPTCHA jest widoczny, czy niewidoczny (wartość domyślna to normalna). Więcej informacji znajdziesz w dokumentacji interfejsu ReCAPTCHA API.

    Można również ustawić kraj domyślny do wpisania numeru telefonu. Pełną listę znajdziesz na liście obsługiwanych kodów krajów. Jeśli numer telefonu nie zostanie określony, domyślnie będzie to Stany Zjednoczone (+1).

    Obecnie obsługiwane są następujące opcje.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
          recaptchaParameters: {
            type: 'image', // 'audio'
            size: 'normal', // 'invisible' or 'compact'
            badge: 'bottomleft' //' bottomright' or 'inline' applies to invisible.
          },
          defaultCountry: 'GB', // Set default country to the United Kingdom (+44).
          // For prefilling the national number, set defaultNationNumber.
          // This will only be observed if only phone Auth provider is used since
          // for multiple providers, the NASCAR screen will always render first
          // with a 'sign in with phone number' button.
          defaultNationalNumber: '1234567890',
          // You can also pass the full phone number string instead of the
          // 'defaultCountry' and 'defaultNationalNumber'. However, in this case,
          // the first country ID that matches the country code will be used to
          // populate the country selector. So for countries that share the same
          // country code, the selected country may not be the expected one.
          // In that case, pass the 'defaultCountry' instead to ensure the exact
          // country is selected. The 'defaultCountry' and 'defaultNationaNumber'
          // will always have higher priority than 'loginHint' which will be ignored
          // in their favor. In this case, the default country will be 'GB' even
          // though 'loginHint' specified the country code as '+1'.
          loginHint: '+11234567890'
        }
      ]
    });
    

Zaloguj się

Aby uruchomić logowanie się w FirebaseUI, zainicjuj instancję FirebaseUI, przekazując bazową instancję Auth.

// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());

Określ element HTML, w którym będzie renderowany widżet logowania FirebaseUI.

<!-- The surrounding HTML is left untouched by FirebaseUI.
     Your app may use that space for branding, controls and other customizations.-->
<h1>Welcome to My Awesome App</h1>
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>

Określ konfigurację FirebaseUI (obsługiwani dostawcy, dostosowania interfejsu użytkownika, skuteczne wywołania zwrotne itp.).

var uiConfig = {
  callbacks: {
    signInSuccessWithAuthResult: function(authResult, redirectUrl) {
      // User successfully signed in.
      // Return type determines whether we continue the redirect automatically
      // or whether we leave that to developer to handle.
      return true;
    },
    uiShown: function() {
      // The widget is rendered.
      // Hide the loader.
      document.getElementById('loader').style.display = 'none';
    }
  },
  // Will use popup for IDP Providers sign-in flow instead of the default, redirect.
  signInFlow: 'popup',
  signInSuccessUrl: '<url-to-redirect-to-on-success>',
  signInOptions: [
    // Leave the lines as is for the providers you want to offer your users.
    firebase.auth.GoogleAuthProvider.PROVIDER_ID,
    firebase.auth.FacebookAuthProvider.PROVIDER_ID,
    firebase.auth.TwitterAuthProvider.PROVIDER_ID,
    firebase.auth.GithubAuthProvider.PROVIDER_ID,
    firebase.auth.EmailAuthProvider.PROVIDER_ID,
    firebase.auth.PhoneAuthProvider.PROVIDER_ID
  ],
  // Terms of service url.
  tosUrl: '<your-tos-url>',
  // Privacy policy url.
  privacyPolicyUrl: '<your-privacy-policy-url>'
};

Na koniec wyrenderuj interfejs uwierzytelniania FirebaseUI:

// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);

Uaktualnianie anonimowych użytkowników

Włączanie anonimowego uaktualniania użytkowników

Gdy anonimowy użytkownik loguje się lub rejestruje stałe konto, musisz mieć pewność, że będzie mógł kontynuować to, co robił, zanim się zarejestruje. Aby to zrobić, ustaw autoUpgradeAnonymousUsers na true podczas konfigurowania interfejsu logowania (ta opcja jest domyślnie wyłączona).

Rozwiązywanie konfliktów podczas scalania anonimowych uaktualnień użytkowników

Może się zdarzyć, że użytkownik, który zalogował się anonimowo, spróbuje przejść na istniejącego użytkownika Firebase. Istniejącego użytkownika nie można połączyć z innym istniejącym użytkownikiem, dlatego FirebaseUI wywoła wywołanie zwrotne signInFailure z kodem błędu firebaseui/anonymous-upgrade-merge-conflict w powyższym przypadku. Obiekt błędu będzie też zawierał trwałe dane logowania. Aby dokończyć logowanie, w wywołaniu zwrotnym powinno być aktywowane logowanie za pomocą trwałych danych logowania. Zanim zalogujesz się za pomocą auth.signInWithCredential(error.credential), musisz zapisać dane anonimowego użytkownika i usunąć anonimowego użytkownika. Po zalogowaniu się skopiuj dane z powrotem do anonimowego użytkownika. Poniższy przykład pokazuje, jak to działa.

// Temp variable to hold the anonymous user data if needed.
var data = null;
// Hold a reference to the anonymous current user.
var anonymousUser = firebase.auth().currentUser;
ui.start('#firebaseui-auth-container', {
  // Whether to upgrade anonymous users should be explicitly provided.
  // The user must already be signed in anonymously before FirebaseUI is
  // rendered.
  autoUpgradeAnonymousUsers: true,
  signInSuccessUrl: '<url-to-redirect-to-on-success>',
  signInOptions: [
    firebase.auth.GoogleAuthProvider.PROVIDER_ID,
    firebase.auth.FacebookAuthProvider.PROVIDER_ID,
    firebase.auth.EmailAuthProvider.PROVIDER_ID,
    firebase.auth.PhoneAuthProvider.PROVIDER_ID
  ],
  callbacks: {
    // signInFailure callback must be provided to handle merge conflicts which
    // occur when an existing credential is linked to an anonymous user.
    signInFailure: function(error) {
      // For merge conflicts, the error.code will be
      // 'firebaseui/anonymous-upgrade-merge-conflict'.
      if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
        return Promise.resolve();
      }
      // The credential the user tried to sign in with.
      var cred = error.credential;
      // Copy data from anonymous user to permanent user and delete anonymous
      // user.
      // ...
      // Finish sign-in after data is copied.
      return firebase.auth().signInWithCredential(cred);
    }
  }
});

Następne kroki