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

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

Прежде чем начать

Для авторизации пользователей с использованием OIDC-провайдера необходимо сначала получить от него некоторую информацию:

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

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

  • Issuer : Строка, идентифицирующая вашего поставщика услуг. Это значение должно представлять собой 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. Укажите свой идентификатор клиента (CTR) и секретный ключ клиента (CTR), а также строку эмитента (Essident string) вашего провайдера. Эти значения должны точно совпадать со значениями, присвоенными вам вашим провайдером.

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

Обрабатывайте процесс авторизации с помощью Firebase SDK.

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

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

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

    Web

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

    Web

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

    Web

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

    Web

    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, помимо базового профиля, которые вы хотите запросить у поставщика аутентификации.

    Web

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

    Web

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

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

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

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

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

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

    Web

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

    Web

    firebase.auth().signInWithRedirect(provider);
    

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

    Web

    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.
      });
    

    Web

    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.
      });
    

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

    Web

    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.
      });
    

    Web

    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:

Web

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.
    });

Web

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.
    });