Catch up on everthing we announced at this year's Firebase Summit. Learn more

Аутентификация с помощью Apple с помощью JavaScript

Вы можете позволить своим пользователям проходить аутентификацию в Firebase с помощью своего Apple ID, используя Firebase SDK для выполнения сквозного потока входа OAuth 2.0.

Прежде чем вы начнете

Чтобы войти в систему пользователей с помощью Apple, сначала настройте Вход с помощью Apple на сайте разработчика Apple, а затем включите Apple в качестве поставщика входа для вашего проекта Firebase.

Присоединяйтесь к программе разработчиков Apple

Войдите с Apple , может быть настроен только членами компании Apple Developer Program .

Настроить вход через Apple

На платформе Apple , сайт, сделайте следующее:

  1. Свяжите свой веб - сайт в приложение , как описано в первом разделе Настройки Входа с Apple , для веба . При появлении запроса зарегистрируйте следующий URL-адрес в качестве URL-адреса возврата:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Вы можете получить свой проект Firebase идентификатор на Firebase консоль Настройки страницы .

    Когда вы закончите, запишите свой новый идентификатор службы, который вам понадобится в следующем разделе.

  2. Создать Вход с Apple , закрытым ключом . В следующем разделе вам понадобятся ваш новый закрытый ключ и идентификатор ключа.
  3. Если вы используете какие - либо из функций Firebase проверки подлинности, что отправлять электронные письма пользователей, в том числе по электронной почте ссылки входа в, адрес электронной почты проверки, изменения счетов аннулирования, а также других, настроить частную службу электронной почты ретрансляционной компании noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com Apple и зарегистрировать noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (или ваш настраиваемый домен шаблона электронной почты), чтобы Apple могла ретранслировать электронные письма, отправленные с помощью Firebase Authentication, на анонимные адреса электронной почты Apple.

Включить Apple в качестве поставщика услуг входа

  1. Добавить Firebase в свой проект .
  2. В Firebase консоли откройте раздел Auth. На вкладке Вход в методе, позволяют поставщику компании Apple. Укажите идентификатор службы, созданный в предыдущем разделе. Кроме того , в разделе конфигурации потока OAuth кода, указать свой Apple , Team ID и секретный ключ и идентификатор ключа, созданный в предыдущем разделе.

Соблюдайте требования Apple к анонимности данных

Вход с помощью Apple , дает пользователям возможность анонимайзер свои данные, включая их адреса электронной почты, при входе в. Пользователи , которые выбирают этот вариант есть адреса электронной почты с доменом privaterelay.appleid.com . Когда вы используете Вход с Apple в своем приложении, вы должны соблюдать все применимые политики или условия Apple для разработчиков в отношении этих анонимных идентификаторов Apple ID.

Это включает получение любого необходимого согласия пользователя перед тем, как вы свяжете любую прямую идентифицирующую личную информацию с анонимным идентификатором Apple ID. При использовании аутентификации Firebase это может включать в себя следующие действия:

  • Свяжите адрес электронной почты с анонимным Apple ID или наоборот.
  • Свяжите номер телефона с анонимным Apple ID или наоборот
  • Свяжите неанонимные учетные данные соцсетей (Facebook, Google и т. Д.) С анонимным идентификатором Apple ID или наоборот.

Приведенный выше список не является исчерпывающим. См. Лицензионное соглашение программы Apple Developer в разделе «Членство» вашей учетной записи разработчика, чтобы убедиться, что ваше приложение соответствует требованиям Apple.

Управляйте входом с помощью Firebase SDK

Если вы создаете веб-приложение, самый простой способ аутентифицировать своих пользователей с помощью Firebase с использованием их учетных записей Apple - это обработать весь процесс входа с помощью Firebase JavaScript SDK.

Чтобы обработать входной поток с помощью Firebase JavaScript SDK, выполните следующие действия:

  1. Создание экземпляра OAuthProvider с использованием соответствующего поставщика ID Apple.com.

    Веб-версия 9

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('apple.com');

    Веб-версия 8

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. Необязательно: Укажите дополнительные OAuth 2.0 областей за пределами по умолчанию , которые вы хотите , чтобы запрос от поставщика проверки подлинности.

    Веб-версия 9

    provider.addScope('email');
    provider.addScope('name');

    Веб-версия 8

    provider.addScope('email');
    provider.addScope('name');

    По умолчанию, когда один счета на адрес электронной почты включен, Firebase запрашивает адрес электронной почты и имя области. Если изменить эту настройку на несколько учетных записей на адрес электронной почты, Firebase не требует каких - либо областей от Apple , если вы не укажете их.

  3. Необязательно: Если вы хотите отобразить входа в Apple, экран на языке , отличном от английского, установить locale параметр. См Вход с Apple , документы для поддерживаемых языков.

    Веб-версия 9

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });

    Веб-версия 8

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. Выполните аутентификацию с помощью Firebase с помощью объекта поставщика OAuth. Вы можете предложить своим пользователям войти в систему со своими учетными записями Apple, открыв всплывающее окно или перенаправив на страницу входа. На мобильных устройствах предпочтительнее использовать метод перенаправления.

    • Для того, чтобы войти в всплывающем окне, вызов signInWithPopup() :

      Веб-версия 9

      import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      signInWithPopup(auth, provider)
        .then((result) => {
          // The signed-in user info.
          const user = result.user;
      
          // Apple credential
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
      
          // ...
        })
        .catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.email;
          // The credential that was used.
          const credential = OAuthProvider.credentialFromError(error);
      
          // ...
        });

      Веб-версия 8

      firebase
        .auth()
        .signInWithPopup(provider)
        .then((result) => {
          /** @type {firebase.auth.OAuthCredential} */
          var credential = result.credential;
      
          // The signed-in user info.
          var user = result.user;
      
          // You can also get the Apple OAuth Access and ID Tokens.
          var accessToken = credential.accessToken;
          var idToken = credential.idToken;
      
          // ...
        })
        .catch((error) => {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
      
          // ...
        });
    • Для того, чтобы войти в систему , перенаправляется на страницу входа, вызовите signInWithRedirect() :

      Веб-версия 9

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

      Веб-версия 8

      firebase.auth().signInWithRedirect(provider);

      После того , как пользователь завершает входа в систему и возвращается на страницу, вы можете получить знак-в результате по телефону getRedirectResult() :

      Веб-версия 9

      import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
      
      // Result from Redirect auth flow.
      const auth = getAuth();
      getRedirectResult(auth)
        .then((result) => {
          const credential = OAuthProvider.credentialFromResult(result);
          if (credential) {
            // You can also get the Apple OAuth Access and ID Tokens.
            const accessToken = credential.accessToken;
            const idToken = credential.idToken;
          }
          // The signed-in user info.
          const user = result.user;
        })
        .catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.email;
          // The credential that was used.
          const credential = OAuthProvider.credentialFromError(error);
      
          // ...
        });

      Веб-версия 8

      // Result from Redirect auth flow.
      firebase
        .auth()
        .getRedirectResult()
        .then((result) => {
          if (result.credential) {
            /** @type {firebase.auth.OAuthCredential} */
            var credential = result.credential;
      
            // You can get the Apple OAuth Access and ID Tokens.
            var accessToken = credential.accessToken;
            var idToken = credential.idToken;
      
            // ...
          }
          // The signed-in user info.
          var user = result.user;
        })
        .catch((error) => {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
      
          // ...
        });

      Здесь также можно выявлять и обрабатывать ошибки. Для получения списка кодов ошибок см ссылки API .

    В отличие от других поставщиков, поддерживаемых Firebase Auth, Apple не предоставляет URL-адрес фотографии.

    Кроме того , когда пользователь выбирает не делиться своей электронной почтой с приложением, положение Apple , уникальный адрес электронной почты для данного пользователя (форм xyz@privaterelay.appleid.com ), который он разделяет с вашим приложением. Если вы настроили частную службу ретрансляции электронной почты, Apple пересылает электронные письма, отправленные на анонимный адрес, на реальный адрес электронной почты пользователя.

    Apple , информация только акции пользователя , такие как отображаемое имя с приложениями , первый раз , когда пользователь входит в систему . Обычно Firebase сохраняет отображаемое имя в первый раз , когда пользователь знаки в с Apple, который вы можете получить с firebase.auth().currentUser.displayName . Однако, если вы ранее использовали Apple для входа пользователя в приложение без использования Firebase, Apple не предоставит Firebase отображаемое имя пользователя.

Повторная аутентификация и привязка аккаунта

Та же модель может быть использована с reauthenticateWithPopup() и reauthenticateWithRedirect() , который можно использовать для извлечения свежих учетных данных для чувствительных операций, требующих вход в последний раз :

Веб-версия 9

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

// Result from Redirect auth flow.
const auth = getAuth();
const provider = new OAuthProvider('apple.com');

reauthenticateWithPopup(auth.currentUser, provider)
  .then((result) => {
    // User is re-authenticated with fresh tokens minted and can perform
    // sensitive operations like account deletion, or updating their email
    // address or password.

    // The signed-in user info.
    const user = result.user;

    // You can also get the Apple OAuth Access and ID Tokens.
    const credential = OAuthProvider.credentialFromResult(result);
    const accessToken = credential.accessToken;
    const idToken = credential.idToken;

    // ...
  })
  .catch((error) => {
    // Handle Errors here.
    const errorCode = error.code;
    const errorMessage = error.message;
    // The email of the user's account used.
    const email = error.email;
    // The credential that was used.
    const credential = OAuthProvider.credentialFromError(error);

    // ...
  });

Веб-версия 8

const provider = new firebase.auth.OAuthProvider('apple.com');

firebase
  .auth()
  .currentUser
  .reauthenticateWithPopup(provider)
  .then((result) => {
    // User is re-authenticated with fresh tokens minted and can perform
    // sensitive operations like account deletion, or updating their email
    // address or password.
    /** @type {firebase.auth.OAuthCredential} */
    var credential = result.credential;

    // The signed-in user info.
    var user = result.user;
     // You can also get the Apple OAuth Access and ID Tokens.
    var accessToken = credential.accessToken;
    var idToken = credential.idToken;

    // ...
  })
  .catch((error) => {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    // The email of the user's account used.
    var email = error.email;
    // The firebase.auth.AuthCredential type that was used.
    var credential = error.credential;

    // ...
  });

И, вы можете использовать linkWithPopup() и linkWithRedirect() , чтобы связать различные провайдер удостоверений для существующих учетных записей.

Обратите внимание, что Apple требует, чтобы вы получили явное согласие пользователей, прежде чем связывать их учетные записи Apple с другими данными.

Например, чтобы связать учетную запись Facebook с текущей учетной записью Firebase, используйте токен доступа, который вы получили при входе пользователя в Facebook:

Веб-версия 9

import { getAuth, linkWithPopup, FacebookAuthProvider } from "firebase/auth";

const auth = getAuth();
const provider = new FacebookAuthProvider();
provider.addScope('user_birthday');

// Assuming the current user is an Apple user linking a Facebook provider.
linkWithPopup(auth.currentUser, provider)
    .then((result) => {
      // Facebook credential is linked to the current Apple user.
      // ...

      // The user can now sign in to the same account
      // with either Apple or Facebook.
    })
    .catch((error) => {
      // Handle error.
    });

Веб-версия 8

const provider = new firebase.auth.FacebookAuthProvider();
provider.addScope('user_birthday');

// Assuming the current user is an Apple user linking a Facebook provider.
firebase.auth().currentUser.linkWithPopup(provider)
    .then((result) => {
      // Facebook credential is linked to the current Apple user.
      // Facebook additional data available in result.additionalUserInfo.profile,

      // Additional Facebook OAuth access token can also be retrieved.
      // result.credential.accessToken

      // The user can now sign in to the same account
      // with either Apple or Facebook.
    })
    .catch((error) => {
      // Handle error.
    });

Аутентифицироваться с помощью Firebase в расширении Chrome

Если вы создаете приложение расширения Chrome, вы должны добавить свой идентификатор расширения Chrome:

  1. Откройте свой проект в консоли Firebase .
  2. В разделе Проверка подлинности, откройте способ входа в страницу.
  3. Добавьте URI как следующий в список авторизованных доменов:
    chrome-extension://CHROME_EXTENSION_ID

Только всплывающие операции ( signInWithPopup , linkWithPopup и reauthenticateWithPopup ) доступны для расширения Chrome, так как расширение Chrome не может использовать HTTP переадресовывает. Эти методы следует вызывать из сценария фоновой страницы, а не из всплывающего окна действия браузера, поскольку всплывающее окно проверки подлинности отменяет всплывающее окно действия браузера. Методы всплывающих окон могут быть использованы только в расширениях с использованием манифеста V2 . Поздние Manifest V3 позволяет только фоновые сценарии в виде работников сферы обслуживания, которые не могут выполнить всплывающие операции на всех.

В расширении Chrome в файле манифеста убедитесь , что вы добавляете https://apis.google.com URL в content_security_policy allowlist.

Обратите внимание, что вы все равно должны подтвердить собственный домен в Apple так же, как домен firebaseapp.com по умолчанию:

http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt

Дополнительно: аутентификация с помощью Firebase в Node.js

Чтобы пройти аутентификацию с помощью Firebase в приложении Node.js:

  1. Войдите в систему пользователя с его учетной записью Apple и получите токен Apple ID пользователя. Вы можете сделать это несколькими способами. Например, если ваше приложение Node.js имеет интерфейс браузера:

    1. На вашем сервере сгенерируйте случайную строку («одноразовый номер») и вычислите ее хэш SHA256. Одноразовый номер - это одноразовое значение, которое вы используете для проверки одного пути туда и обратно между вашим бэкэндом и серверами аутентификации Apple.

      Веб-версия 9

      const crypto = require("crypto");
      const string_decoder = require("string_decoder");
      
      // Generate a new random string for each sign-in
      const generateNonce = (length) => {
        const decoder = new string_decoder.StringDecoder("ascii");
        const buf = Buffer.alloc(length);
        let nonce = "";
        while (nonce.length < length) {
          crypto.randomFillSync(buf);
          nonce = decoder.write(buf);
        }
        return nonce.substr(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');

      Веб-версия 8

      const crypto = require("crypto");
      const string_decoder = require("string_decoder");
      
      // Generate a new random string for each sign-in
      const generateNonce = function(length) {
        const decoder = new string_decoder.StringDecoder("ascii");
        const buf = Buffer.alloc(length);
        var nonce = "";
        while (nonce.length < length) {
          crypto.randomFillSync(buf);
          nonce = decoder.write(buf);
        }
        return nonce.substr(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');
    2. На странице входа укажите хешированный одноразовый номер в конфигурации входа с помощью Apple:

      <script src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>
      <div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div>
      <script>
          AppleID.auth.init({
              clientId: YOUR_APPLE_CLIENT_ID,
              scope: 'name email',
              redirectURI: URL_TO_YOUR_REDIRECT_HANDLER,  // See the next step.
              state: '[STATE]',  // Optional value that Apple will send back to you
                                 // so you can return users to the same context after
                                 // they sign in.
              nonce: HASHED_NONCE  // The hashed nonce you generated in the previous step.
          });
      </script>
      
    3. Получите токен Apple ID со стороны сервера POSTed auth response:

      app.post('/redirect', (req, res) => {
        const savedState = req.cookies.__session;
        const code = req.body.code;
        const state = req.body.state;
        const appleIdToken = req.body.id_token;
        if (savedState !== state || !code) {
          res.status(403).send('403: Permission denied');
        } else {
          // Sign in with Firebase using appleIdToken. (See next step).
        }
      });
      

    Также см Настройка веб - страницы для Входа с Яблоком .

  2. После того, как вы получите токен Apple ID пользователя, используйте его для создания объекта Credential, а затем войдите в систему с учетными данными:

    Веб-версия 9

    import { getAuth, signInWithCredential, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    
    // Build Firebase credential with the Apple ID token.
    const provider = new OAuthProvider('apple.com');
    const authCredential = provider.credential({
      idToken: appleIdToken,
      rawNonce: unhashedNonce,
    });
    
    // Sign in with credential form the Apple user.
    signInWithCredential(auth, authCredential)
      .then((result) => {
        // User signed in.
      })
      .catch((error) => {
        // An error occurred. If error.code == 'auth/missing-or-invalid-nonce',
        // make sure you're sending the SHA256-hashed nonce as a hex string
        // with your request to Apple.
        console.log(error);
      });

    Веб-версия 8

    // Build Firebase credential with the Apple ID token.
    const provider = new firebase.auth.OAuthProvider('apple.com');
    const authCredential = provider.credential({
      idToken: appleIdToken,
      rawNonce: unhashedNonce,
    });
    
    // Sign in with credential form the Apple user.
    firebase.auth().signInWithCredential(authCredential)
      .then((result) => {
        // User signed in.
      })
      .catch((error) => {
        // An error occurred. If error.code == 'auth/missing-or-invalid-nonce',
        // make sure you're sending the SHA256-hashed nonce as a hex string
        // with your request to Apple.
        console.log(error);
      });

Следующие шаги

После того, как пользователь входит в систему в первый раз, создается новая учетная запись пользователя, связанная с учетными данными, то есть с именем пользователя и паролем, номером телефона или информацией о провайдере аутентификации, с которыми пользователь вошел в систему. Эта новая учетная запись хранится как часть вашего проекта Firebase и может использоваться для идентификации пользователя в каждом приложении в вашем проекте, независимо от того, как пользователь входит в систему.

  • В приложениях, рекомендуемый способ узнать статус аутентификации вашего пользователя, чтобы установить наблюдатель на Auth объекте. Вы можете получить основную информацию о профиле пользователя от User объекта. См Управление пользователей .

  • В вашей базе данных в реальном времени и Firebase Cloud Storage правил безопасности , вы можете получить подписанный в уникальном пользователя идентификатор пользователя из 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.
});