Аутентификация с помощью OpenID Connect в веб-приложениях

Если вы перешли на Firebase Authentication with Identity Platform, вы можете аутентифицировать своих пользователей с помощью Firebase, используя поставщика, совместимого с OpenID Connect (OIDC), по вашему выбору. Это позволяет использовать поставщиков удостоверений, изначально не поддерживаемых Firebase.

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

Чтобы войти в систему с помощью поставщика OIDC, необходимо сначала получить некоторую информацию от поставщика:

  • Идентификатор клиента : строка, уникальная для поставщика, которая идентифицирует ваше приложение. Ваш провайдер может назначить вам разные идентификаторы клиентов для каждой поддерживаемой вами платформы. Это одно из значений утверждения aud в токенах ID, выданных вашим провайдером.

  • Секрет клиента : секретная строка, которую поставщик использует для подтверждения владения идентификатором клиента. Для каждого идентификатора клиента вам потребуется соответствующий секрет клиента. (Это значение требуется, только если вы используете поток кода авторизации , что настоятельно рекомендуется.)

  • Эмитент : строка, идентифицирующая вашего провайдера. Это значение должно быть URL-адресом, который при добавлении к нему /.well-known/openid-configuration является расположением документа обнаружения OIDC поставщика. Например, если издателем является https://auth.example.com , документ обнаружения должен быть доступен по https://auth.example.com/.well-known/openid-configuration .

Получив указанную выше информацию, включите OpenID Connect в качестве поставщика входа для вашего проекта Firebase:

  1. Добавьте Firebase в свой проект JavaScript .

  2. Если вы еще не перешли на Firebase Authentication with Identity Platform, сделайте это. Аутентификация OpenID Connect доступна только в обновленных проектах.

  3. На странице «Поставщики входа» в консоли Firebase нажмите «Добавить нового поставщика» , а затем нажмите «OpenID Connect» .

  4. Выберите, будете ли вы использовать поток кода авторизации или неявный поток предоставления .

    Вы всегда должны использовать поток кода, если ваш провайдер поддерживает его . Неявный поток менее безопасен, и его использование настоятельно не рекомендуется.

  5. Дайте имя этому провайдеру. Обратите внимание на сгенерированный идентификатор провайдера: что-то вроде oidc.example-provider . Этот идентификатор понадобится вам при добавлении кода входа в приложение.

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

  7. Сохраните изменения.

Обработка процесса входа с помощью Firebase SDK

Самый простой способ аутентификации пользователей в Firebase с помощью вашего поставщика OIDC — это обработка всего процесса входа с помощью Firebase SDK.

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

  1. Создайте экземпляр OAuthProvider используя идентификатор поставщика, полученный в консоли Firebase.

    Модульный веб-API

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('oidc.example-provider');
    

    Веб-API с пространством имен

    var provider = new firebase.auth.OAuthProvider('oidc.example-provider');
    
  2. Необязательно : укажите дополнительные настраиваемые параметры OAuth, которые вы хотите отправить с запросом OAuth.

    Модульный веб-API

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

    Веб-API с пространством имен

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

    Узнайте у своего провайдера, какие параметры он поддерживает. Обратите внимание, что вы не можете передавать параметры, необходимые для Firebase, с помощью setCustomParameters . Это параметры client_id , response_type , redirect_uri , state , scope и response_mode .

  3. Необязательно : укажите дополнительные области OAuth 2.0 помимо базового профиля, которые вы хотите запросить у поставщика проверки подлинности.

    Модульный веб-API

    provider.addScope('mail.read');
    provider.addScope('calendars.read');
    

    Веб-API с пространством имен

    provider.addScope('mail.read');
    provider.addScope('calendars.read');
    

    Узнайте у своего провайдера, какие области он поддерживает.

  4. Выполните аутентификацию в Firebase, используя объект поставщика OAuth.

    Вы можете либо перенаправить пользователя на страницу входа провайдера, либо открыть страницу входа во всплывающем окне браузера.

    Перенаправить поток

    Перенаправить на страницу входа провайдера, вызвав signInWithRedirect() :

    Модульный веб-API

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

    Веб-API с пространством имен

    firebase.auth().signInWithRedirect(provider);
    

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

    Модульный веб-API

    import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        // User is signed in.
        // 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.
      });
    

    Веб-API с пространством имен

    firebase.auth().getRedirectResult()
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    

    Всплывающий поток

    Модульный веб-API

    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        // IdP data available using getAdditionalUserInfo(result)
    
        // 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.
      });
    

    Веб-API с пространством имен

    firebase.auth().signInWithPopup(provider)
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    
  5. Хотя в приведенных выше примерах основное внимание уделяется потокам входа, вы можете использовать тот же шаблон, чтобы связать поставщика OIDC с существующим пользователем с помощью linkWithRedirect() и linkWithPopup() , а также повторно аутентифицировать пользователя с помощью reauthenticateWithRedirect() и reauthenticateWithPopup() . который можно использовать для получения новых учетных данных для конфиденциальных операций, требующих недавнего входа в систему.

Обработка процесса входа вручную

Если вы уже внедрили процесс входа OpenID Connect в свое приложение, вы можете использовать токен ID напрямую для аутентификации в Firebase:

Модульный веб-API

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

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
signInWithCredential(getAuth(), credential)
    .then((result) => {
        // User is signed in.
        // 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.
    });

Веб-API с пространством имен

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
firebase.auth().signInWithCredential(credential)
    .then((result) => {
        // User is signed in.
        // 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.
    });