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

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

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

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

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

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

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

    WebWeb
    import { OAuthProvider } from "firebase/auth";

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

    WebWeb
    provider.setCustomParameters({
     
    // Target specific email with login hint.
      login_hint
    : 'user@example.com'
    });
    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 помимо базового профиля, которые вы хотите запросить у поставщика аутентификации.

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

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

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

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

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

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

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

    const auth = getAuth();
    signInWithRedirect
    (auth, provider);
    firebase.auth().signInWithRedirect(provider);

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

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

    Всплывающее окно

    WebWeb
    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.
     
    });
    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 в свое приложение, вы можете использовать токен идентификатора напрямую для аутентификации в Firebase:

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