Uwierzytelniaj przy użyciu Yahoo z JavaScriptem

Możesz pozwolić użytkownikom na uwierzytelnianie się w Firebase za pomocą dostawców OAuth, takich jak Yahoo. Aby umożliwić im logowanie się w ramach całego procesu, zintegruj w swojej aplikacji logowanie OAuth za pomocą pakietu SDK Firebase.

Zanim zaczniesz

Aby umożliwić użytkownikom logowanie się za pomocą kont Yahoo, musisz najpierw włączyć Yahoo jako dostawcę logowania w projekcie Firebase:

  1. Dodaj Firebase do projektu JavaScript.
  2. W konsoli Firebase otwórz sekcję Autoryzacja.
  3. Na karcie Metoda logowania włącz dostawcę Yahoo.
  4. Dodaj Identyfikator klienta i Tajny klucz klienta z konsoli deweloperskiej tego dostawcy do konfiguracji tego dostawcy:
    1. Aby zarejestrować klienta OAuth Yahoo, postępuj zgodnie z  dokumentacją dla deweloperów Yahoo dotyczącą rejestrowania aplikacji internetowej w Yahoo.

      Pamiętaj, aby wybrać 2 uprawnienia interfejsu OpenID Connect API: profileemail.

    2. Podczas rejestrowania aplikacji u tych dostawców pamiętaj, aby zarejestrować domenę *.firebaseapp.com dla projektu jako domenę przekierowania dla aplikacji.
  5. Kliknij Zapisz.

Obsługa procesu logowania za pomocą pakietu SDK Firebase

Jeśli tworzysz aplikację internetową, najprostszym sposobem uwierzytelniania użytkowników Firebase za pomocą ich kont Yahoo jest przeprowadzenie całego procesu logowania za pomocą pakietu Firebase JavaScript SDK.

Aby obsłużyć proces logowania za pomocą pakietu Firebase JavaScript SDK, wykonaj te czynności:

  1. Utwórz instancję OAuthProvider, używając identyfikatora dostawcy yahoo.com.

    WebWeb
    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('yahoo.com');
    var provider = new firebase.auth.OAuthProvider('yahoo.com');
  2. Opcjonalnie: określ dodatkowe niestandardowe parametry OAuth, które chcesz wysłać z prośbą OAuth.

    WebWeb
    provider.setCustomParameters({
      // Prompt user to re-authenticate to Yahoo.
      prompt: 'login',
      // Localize to French.
      language: 'fr'
    });  
    provider.setCustomParameters({
      // Prompt user to re-authenticate to Yahoo.
      prompt: 'login',
      // Localize to French.
      language: 'fr'
    });  

    Informacje o parametrach obsługiwanych przez Yahoo! znajdziesz w dokumentacji OAuth Yahoo!. Pamiętaj, że za pomocą parametru setCustomParameters() nie możesz przekazywać parametrów wymaganych przez Firebase. Są to: client_id, redirect_uri, response_type, scope i state.

  3. Opcjonalnie: określ dodatkowe zakresy OAuth 2.0 poza profile i email, o które chcesz poprosić dostawcę uwierzytelniania. Jeśli Twoja aplikacja wymaga dostępu do prywatnych danych użytkownika z interfejsów Yahoo, musisz poprosić o uprawnienia do interfejsów Yahoo w sekcji Uprawnienia interfejsu API w Konsoli deweloperów Yahoo. Żądane zakresy uprawnień OAuth muszą dokładnie odpowiadać zakresom skonfigurowanym w uprawnieniach interfejsu API aplikacji. Jeśli na przykład żądasz dostępu do kontaktów użytkownika na potrzeby odczytu i zapisu, a uprawnienia w interfejsie API aplikacji są skonfigurowane wstępnie, zamiast zakresu OAuth tylko do odczytu sdct-r musisz podać wartość sdct-w. W przeciwnym razie proces się nie powiedzie i użytkownik zobaczy komunikat o błędzie.

    WebWeb
    // Request access to Yahoo Mail API.
    provider.addScope('mail-r');
    // Request read/write access to user contacts.
    // This must be preconfigured in the app's API permissions.
    provider.addScope('sdct-w');
    // Request access to Yahoo Mail API.
    provider.addScope('mail-r');
    // Request read/write access to user contacts.
    // This must be preconfigured in the app's API permissions.
    provider.addScope('sdct-w');

    Więcej informacji znajdziesz w dokumentacji zakresów Yahoo.

  4. Uwierzytelnij się w Firebase, używając obiektu dostawcy OAuth. Możesz poprosić użytkowników o zalogowanie się na swoje konta Yahoo, otwierając okno wyskakujące lub przekierowując ich na stronę logowania. Na urządzeniach mobilnych preferowana jest metoda przekierowania.

    • Aby zalogować się w wyskakującym okienku, zadzwoń pod numer signInWithPopup:

      WebWeb
      import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      signInWithPopup(auth, provider)
        .then((result) => {
          // IdP data available in result.additionalUserInfo.profile
          // ...
      
          // Yahoo OAuth access token and ID token can be retrieved by calling:
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
      firebase.auth().signInWithPopup(provider)
        .then((result) => {
          // IdP data available in result.additionalUserInfo.profile
          // ...
      
          /** @type {firebase.auth.OAuthCredential} */
          const credential = result.credential;
      
          // Yahoo OAuth access token and ID token can be retrieved by calling:
          var accessToken = credential.accessToken;
          var idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
    • Aby zalogować się przez przekierowanie na stronę logowania, zadzwoń pod numer signInWithRedirect:

    Stosuj sprawdzone metody podczas używania funkcji signInWithRedirect, linkWithRedirect lub reauthenticateWithRedirect.

      firebase.auth().signInWithRedirect(provider);
      

    Gdy użytkownik zakończy logowanie i wróci na stronę, możesz uzyskać wynik logowania, wywołując funkcję getRedirectResult.

    WebWeb
    import { getAuth, signInWithRedirect } from "firebase/auth";
    
    const auth = getAuth();
    signInWithRedirect(auth, provider);
    firebase.auth().signInWithRedirect(provider);

    Po pomyślnym zakończeniu procesu z zwróconego obiektu firebase.auth.UserCredential można pobrać token identyfikatora OAuth i token dostępu powiązane z dostawcą.

    Za pomocą tokena dostępu OAuth możesz wywoływać interfejs Yahoo API.

    Aby na przykład uzyskać podstawowe informacje o profilu, możesz wywołać ten interfejs API REST:

    curl -i -H "Authorization: Bearer ACCESS_TOKEN" https://social.yahooapis.com/v1/user/YAHOO_USER_UID/profile?format=json

    Gdzie YAHOO_USER_UID to identyfikator użytkownika Yahoo, który można pobrać z pola firebase.auth().currentUser.providerData[0].uid lub z result.additionalUserInfo.profile.

  5. Powyższe przykłady koncentrują się na procesach logowania, ale za pomocą parametrów linkWithPopup/linkWithRedirect możesz też powiązać dostawcę Yahoo z dotychczasowym użytkownikiem. Możesz na przykład powiązać kilku dostawców z tym samym użytkownikiem, aby umożliwić mu logowanie się za pomocą dowolnego z nich.

    WebWeb
    import { getAuth, linkWithPopup, OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('yahoo.com');
    const auth = getAuth();
    linkWithPopup(auth.currentUser, provider)
        .then((result) => {
          // Yahoo credential is linked to the current user.
          // IdP data available in result.additionalUserInfo.profile.
    
          // Get the OAuth access token and ID Token
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
    var provider = new firebase.auth.OAuthProvider('yahoo.com');
    firebase.auth().currentUser.linkWithPopup(provider)
        .then((result) => {
          // Yahoo credential is linked to the current user.
          // IdP data available in result.additionalUserInfo.profile.
          // Yahoo OAuth access token can be retrieved by calling:
          // result.credential.accessToken
          // Yahoo OAuth ID token can be retrieved by calling:
          // result.credential.idToken
        })
        .catch((error) => {
          // Handle error.
        });
  6. Tego samego wzorca można używać w przypadku parametrów reauthenticateWithPopup/reauthenticateWithRedirect, które umożliwiają pobieranie nowych danych logowania w przypadku operacji wrażliwych wymagających niedawnego zalogowania.

    WebWeb
    import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('yahoo.com');
    const auth = getAuth();
    reauthenticateWithPopup(auth.currentUser, provider)
        .then((result) => {
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
    
          // Get the OAuth access token and ID Token
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
    var provider = new firebase.auth.OAuthProvider('yahoo.com');
    firebase.auth().currentUser.reauthenticateWithPopup(provider)
        .then((result) => {
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
          // Yahoo OAuth access token can be retrieved by calling:
          // result.credential.accessToken
          // Yahoo OAuth ID token can be retrieved by calling:
          // result.credential.idToken
        })
        .catch((error) => {
          // Handle error.
        });

Jeśli w konsoli Firebase włączysz ustawienie Jedno konto na adres e-mail, gdy użytkownik spróbuje zalogować się do dostawcy (np. Yahoo) za pomocą adresu e-mail, który już istnieje w przypadku dostawcy innego użytkownika Firebase (np. Google), zostanie zwrócony błądauth/account-exists-with-different-credential wraz z obiektemAuthCredential (dane logowania Yahoo). Aby dokończyć logowanie do wybranego dostawcy, użytkownik musi najpierw zalogować się w dostawcy, którego używa obecnie (Google), a potem połączyć konto z tym dostawcą AuthCredential (dane logowania Yahoo).

Jeśli używasz signInWithPopup, możesz obsługiwać błędy auth/account-exists-with-different-credential za pomocą kodu podobnego do tego:

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

try {
  // Step 1: User tries to sign in using Yahoo.
  let result = await signInWithPopup(getAuth(), new OAuthProvider());
} catch (error) {
  // Step 2: User's email already exists.
  if (error.code === "auth/account-exists-with-different-credential") {
    // The pending Yahoo credential.
    let pendingCred = error.credential;

    // Step 3: Save the pending credential in temporary storage,

    // Step 4: Let the user know that they already have an account
    // but with a different provider, and let them choose another
    // sign-in method.
  }
}

// ...

try {
  // Step 5: Sign the user in using their chosen method.
  let result = await signInWithPopup(getAuth(), userSelectedProvider);

  // Step 6: Link to the Yahoo credential.
  // TODO: implement `retrievePendingCred` for your app.
  let pendingCred = retrievePendingCred();

  if (pendingCred !== null) {
    // As you have access to the pending credential, you can directly call the
    // link method.
    let user = await linkWithCredential(result.user, pendingCred);
  }

  // Step 7: Continue to app.
} catch (error) {
  // ...
}

Tryb przekierowania

Ten błąd jest obsługiwany w podobny sposób w trybie przekierowania, z tą różnicą, że oczekujące dane logowania muszą zostać zapisane w pamięci podręcznej między przekierowaniami stron (np. za pomocą pamięci sesji).

W odróżnieniu od innych dostawców OAuth obsługiwanych przez Firebase, takich jak Google, Facebook i Twitter, gdzie logowanie można przeprowadzić bezpośrednio za pomocą danych logowania opartych na tokenach dostępu OAuth, usługa Firebase Auth nie obsługuje tej samej funkcji w przypadku dostawców takich jak Yahoo, ponieważ serwer Firebase Auth nie może zweryfikować odbiorców tokenów dostępu OAuth Yahoo. Jest to kluczowe wymaganie bezpieczeństwa, ponieważ aplikacje i witryny mogą być narażone na ataki polegające na odtwarzaniu, w których token dostępu OAuth Yahoo uzyskany dla jednego projektu (atakujący) może być użyty do zalogowania się w innym projekcie (ofiara). Zamiast tego Firebase Auth umożliwia obsługę całego procesu OAuth i wymiany kodu autoryzacji za pomocą identyfikatora klienta OAuth i tajemnego klucza skonfigurowanych w Konsoli Firebase. Kod autoryzacji można użyć tylko w połączeniu z konkretnym identyfikatorem klienta lub kluczem tajnym. Kod autoryzacji uzyskany w jednym projekcie nie może być użyty w innym.

Jeśli te usługi są wymagane w nieobsługiwanych środowiskach, musisz użyć biblioteki OAuth innej firmy i niestandardowej autoryzacji Firebase. Pierwszy z nich jest potrzebny do uwierzytelnienia się u dostawcy, a drugi do wymiany danych logowania dostawcy na token niestandardowy.

Uwierzytelnianie w Firebase w rozszerzeniu do Chrome

Jeśli tworzysz rozszerzenie do Chrome, zapoznaj się z  przewodnikiem po dokumentach poza ekranem.

Podczas tworzenia projektu Firebase udostępni unikalną domenę podrzędną dla Twojego projektu:https://my-app-12345.firebaseapp.com.

Będzie on też używany jako mechanizm przekierowania w przypadku logowania OAuth. Ta domena musi być dozwolona dla wszystkich obsługiwanych dostawców OAuth. Oznacza to jednak, że użytkownicy mogą zobaczyć tę domenę podczas logowania się w Yahoo, zanim zostaną przekierowani z powrotem do aplikacji: Przejdź na https://my-app-12345.firebaseapp.com.

Aby uniknąć wyświetlania subdomeny, możesz skonfigurować domenę niestandardową za pomocą Firebase Hosting:

  1. Wykonaj czynności opisane w sekwencji Konfigurowanie domeny dla usługi Hosting. Gdy potwierdzisz własność domeny, Hosting zarezerwuje certyfikat SSL dla Twojej domeny niestandardowej.
  2. Dodaj swoją domenę niestandardową do listy autoryzowanych domen w konsoli Firebase: auth.custom.domain.com.
  3. W konsoli deweloperów Yahoo lub na stronie konfiguracji OAuth dodaj do białej listy adres URL strony przekierowania, która będzie dostępna w Twojej domenie niestandardowej:https://auth.custom.domain.com/__/auth/handler.
  4. Podczas inicjowania biblioteki JavaScript podaj domenę niestandardową w polu authDomain:
    var config = {
      apiKey: '...',
      // Changed from 'PROJECT_ID.firebaseapp.com'.
      authDomain: 'auth.custom.domain.com',
      databaseURL: 'https://PROJECT_ID.firebaseio.com',
      projectId: 'PROJECT_ID',
      storageBucket: 'PROJECT_ID.firebasestorage.app',
      messagingSenderId: 'SENDER_ID'
    };
    firebase.initializeApp(config);

Dalsze kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z danymi logowania, czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami dostawcy uwierzytelniania, za pomocą których użytkownik się zalogował. To nowe konto jest przechowywane w projekcie Firebase i może służyć do identyfikowania użytkownika we wszystkich aplikacjach w projekcie, niezależnie od tego, jak użytkownik się loguje.

  • W swoich aplikacjach zalecamy ustalanie stanu uwierzytelniania użytkownika przez ustawienie obserwatora w obiekcie Auth. Następnie możesz uzyskać podstawowe informacje o profilu użytkownika z obiektu User. Zobacz Zarządzanie użytkownikami.

  • W regułach Firebase Realtime DatabaseCloud Storage Regułach bezpieczeństwa możesz pobrać z zmiennej auth unikalny identyfikator zalogowanego użytkownika i używać go do kontrolowania dostępu użytkownika do danych.

Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą danych uwierzytelniających od różnych dostawców, łącząc je z dotychczasowym kontem użytkownika.

Aby wylogować użytkownika, wywołaj funkcję signOut:

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

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