Secure Data Connect с авторизацией и аттестацией, Secure Data Connect с авторизацией и аттестацией, Secure Data Connect с авторизацией и аттестацией

Firebase Data Connect обеспечивает надежную безопасность на стороне клиента благодаря:

  • Авторизация в мобильном и веб-клиенте
  • Индивидуальный контроль авторизации на уровне запроса и мутации
  • Аттестация приложения с помощью Firebase App Check .

Data Connect расширяет эту безопасность за счет:

  • Авторизация на стороне сервера
  • Проект Firebase и безопасность пользователей Cloud SQL с помощью IAM.

Авторизация клиентских запросов и изменений

Data Connect полностью интегрирован с Firebase Authentication , поэтому вы можете использовать обширные данные о пользователях, которые получают доступ к вашим данным (аутентификация), в своем проекте для определения того, к каким данным эти пользователи могут получить доступ (авторизация).

Data Connect предоставляет директиву @auth для запросов и изменений, которая позволяет вам установить уровень аутентификации, необходимый для авторизации операции. В этом руководстве представлена ​​директива @auth с примерами .

Кроме того, Data Connect поддерживает выполнение запросов, встроенных в мутации, поэтому вы можете получить дополнительные критерии авторизации, которые вы сохранили в своей базе данных, и использовать эти критерии в директивах @check чтобы решить, разрешены ли включающие мутации. В этом случае авторизации директива @redact позволяет контролировать, возвращаются ли результаты запроса клиентам по проводному протоколу, а встроенный запрос опускается в сгенерированных SDK. Найдите введение к этим директивам с примерами .

Понимание директивы @auth

Вы можете параметризовать директиву @auth , чтобы она соответствовала одному из нескольких предустановленных уровней доступа, которые охватывают множество распространенных сценариев доступа. Эти уровни варьируются от PUBLIC (который разрешает запросы и изменения от всех клиентов без какой-либо аутентификации) до NO_ACCESS (который запрещает запросы и изменения за пределами привилегированных серверных сред с использованием Firebase Admin SDK ). Каждый из этих уровней коррелирует с потоками аутентификации, предоставляемыми Firebase Authentication .

Уровень Определение
PUBLIC Операцию может выполнить любой человек с аутентификацией или без нее.
PUBLIC Операцию может выполнить любой человек с аутентификацией или без нее.
USER_ANON Любой идентифицированный пользователь, включая тех, кто вошел в систему анонимно с помощью Firebase Authentication , имеет право выполнять запрос или мутацию.
USER Любой пользователь, вошедший в систему с помощью Firebase Authentication имеет право выполнять запрос или мутацию, за исключением анонимных пользователей, вошедших в систему.
USER_EMAIL_VERIFIED Любой пользователь, вошедший в систему с помощью Firebase Authentication с подтвержденным адресом электронной почты, имеет право выполнить запрос или мутацию.
NO_ACCESS Эту операцию нельзя выполнить вне контекста Admin SDK.

Используя эти предустановленные уровни доступа в качестве отправной точки, вы можете определить сложные и надежные проверки авторизации в директиве @auth используя where и выражения Common Expression Language (CEL), оцениваемые на сервере.

Используйте директиву @auth для реализации распространенных сценариев авторизации.

Предустановленные уровни доступа являются отправной точкой для авторизации.

Уровень доступа USER — это наиболее широко используемый базовый уровень для начала.

Полностью безопасный доступ будет основан на уровне USER а также на фильтрах и выражениях, которые проверяют атрибуты пользователя, атрибуты ресурсов, роли и другие проверки. Уровни USER_ANON и USER_EMAIL_VERIFIED являются вариациями регистра USER .

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

Конечно, есть случаи использования, когда PUBLIC — это правильный уровень доступа для начала. Опять же, уровень доступа всегда является отправной точкой, и для надежной безопасности необходимы дополнительные фильтры и выражения.

В этом руководстве приведены примеры того, как использовать USER и PUBLIC .

Мотивирующий пример

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

Такая платформа, скорее всего, будет моделировать Users и Posts .

type User @table(key: "uid") {
  uid: String!
  name: String
  birthday: Date
  createdAt: Timestamp! @default(expr: "request.time")
}

type Post @table {
  author: User!
  text: String!
  # "one of 'draft', 'public', or 'pro'"
  visibility: String! @default(value: "draft")
  # "the time at which the post should be considered published. defaults to
  # immediately"
  publishedAt: Timestamp! @default(expr: "request.time")
  createdAt: Timestamp! @default(expr: "request.time")
  updatedAt: Timestamp! @default(expr: "request.time")
}

Ресурсы, принадлежащие пользователям

Firebase рекомендует писать фильтры и выражения, которые проверяют право собственности пользователя на ресурс, в следующих случаях — право собственности на Posts .

В следующих примерах данные из токенов аутентификации считываются и сравниваются с помощью выражений. Типичным шаблоном является использование таких выражений, как where: {authorUid: {eq_expr: "auth.uid"}} для сравнения сохраненного authorUid с auth.uid (идентификатором пользователя), переданным в токене аутентификации.

Создавать

Эта практика авторизации начинается с добавления auth.uid из токена аутентификации в каждое новое Post в качестве authorUid чтобы обеспечить возможность сравнения в тестах авторизации подпоследовательности.

# Create a new post as the current user
mutation CreatePost($text: String!, $visibility: String) @auth(level: USER) {
  post_insert(data: {
    # set the author's uid to the current user uid
    authorUid_expr: "auth.uid"
    text: $text
    visibility: $visibility
  })
}
Обновлять

Когда клиент пытается обновить Post , вы можете проверить переданный auth.uid на соответствие authorUid .

# Update one of the current user's posts
mutation UpdatePost($id: UUID!, $text: String, $visibility: String) @auth(level:USER) {
  post_update(
    # only update posts whose author is the current user
    first: { where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}
    }}
    data: {
      text: $text
      visibility: $visibility
      # insert the current server time for updatedAt
      updatedAt_expr: "request.time"
    }
  )
}
Удалить

Тот же метод используется для авторизации операций удаления.

# Delete one of the current user's posts
mutation DeletePost($id: UUID!) @auth(level: USER) {
  post_delete(
    # only delete posts whose author is the current user
    first: { where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}
    }}
  )
}
# Common display information for a post
fragment DisplayPost on Post {
  id, text, createdAt, updatedAt
  author { uid, name }
}
Список
# List all posts belonging to the current user
query ListMyPosts @auth(level: USER) {
  posts(where: {
    userUid: {eq_expr: "auth.uid"}
  }) {
    # See the fragment above
    ...DisplayPost
    # also show visibility since it is user-controlled
    visibility
  }
}
Получать
# Get a post only if it belongs to the current user
query GetMyPost($id: UUID!) @auth(level: USER) {
  post(key: {id: $id},
    first: {where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}}
      }}, {
      # See the fragment above
      ...DisplayPost
      # also show visibility since it is user-controlled
      visibility
  }
}

Фильтровать данные

Система авторизации Data Connect позволяет создавать сложные фильтры в сочетании с предустановленными уровнями доступа, такими как PUBLIC а также с использованием данных из токенов аутентификации.

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

Фильтровать по атрибутам ресурса

Здесь авторизация не основана на токенах аутентификации, поскольку базовый уровень безопасности установлен на PUBLIC . Но мы можем явно установить записи в нашей базе данных как подходящие для публичного доступа; Предположим, что в нашей базе данных есть записи Post с visibility установленной на «публичный».

# List all posts marked as 'public' visibility
query ListPublicPosts @auth(level: PUBLIC) {
  posts(where: {
    # Test that visibility is "public"
    visibility: {eq: "public"}
    # Only display articles that are already published
    publishedAt: {lt_expr: "request.time"}
  }) {
    # see the fragment above
    ...DisplayPost
  }
}
Фильтровать по заявлениям пользователей

Предположим, вы настроили пользовательские утверждения, которые передают токены аутентификации для идентификации пользователей в плане «Pro» для вашего приложения, помеченных полем auth.token.plan в токене аутентификации. Ваши выражения можно проверить по этому полю.

# List all public or pro posts, only permitted if user has "pro" plan claim
query ProListPosts @auth(expr: "auth.token.plan == 'pro'") {
  posts(where: {
    # display both public posts and "pro" posts
    visibility: {in: ['public', 'pro']},
    # only display articles that are already published
    publishedAt: {lt_expr: "request.time"},
  }) {
    # see the fragment above
    ...DisplayPost
    # show visibility so pro users can see which posts are pro\
    visibility
  }
}
Фильтровать по заказу + лимиту

Или, опять же, вы можете настроить visibility в записях Post , чтобы определить, что они являются контентом, доступным для «профессиональных» пользователей, но для предварительного просмотра или тизерного списка данных дополнительно ограничьте количество возвращаемых записей.

# Show 2 oldest Pro post as a preview
query ProTeaser @auth(level: USER) {
  posts(
    where: {
      # show only pro posts
      visibility: {eq: "pro"}
      # that have already been published more than 30 days ago
      publishedAt: {lt_time: {now: true, sub: {days: 30}}}
    },
    # order by publish time
    orderBy: [{publishedAt: DESC}],
    # only return two posts
    limit: 2
  ) {
    # See the fragment above
    ...DisplayPost
  }
}
Фильтровать по роли

Если в вашем пользовательском утверждении определена роль admin , вы можете соответствующим образом протестировать и авторизовать операции.

# List all posts unconditionally iff the current user has an admin claim
query AdminListPosts @auth(expr: "auth.token.admin == true") {
  posts { ...DisplayPost }
}

Понимание директив @check и @redact

Директива @check проверяет наличие указанных полей в результатах запроса. Выражение Common Expression Language (CEL) используется для проверки значений полей. Поведение директивы по умолчанию — проверять и отклонять узлы с null значением.

Директива @redact редактирует часть ответа клиента. Отредактированные поля по-прежнему оцениваются на наличие побочных эффектов (включая изменения данных и @check ), а результаты по-прежнему доступны для последующих шагов в выражениях CEL.

В Data Connect директивы @check и @redact чаще всего используются в контексте проверок авторизации; обратитесь к обсуждению поиска данных авторизации .

Добавьте директивы @check и @redact для поиска данных авторизации.

Распространенный вариант использования авторизации включает сохранение пользовательских ролей авторизации в вашей базе данных, например, в специальной таблице разрешений, и использование этих ролей для авторизации мутаций для создания, обновления или удаления данных.

Используя поиск данных авторизации, вы можете запрашивать роли на основе идентификатора пользователя и использовать выражения CEL, чтобы решить, разрешена ли мутация. Например, вы можете написать мутацию UpdateMovieTitle , которая позволит авторизованному клиенту обновлять названия фильмов.

В оставшейся части обсуждения предположим, что база данных приложения для просмотра фильмов хранит роль авторизации в таблице MoviePermission .

# MoviePermission
# Suppose a user has an authorization role with respect to records in the Movie table
type MoviePermission @table(key: ["doc", "userId"]) {
  movie: Movie! # implies another field: movieId: UUID!
  userId: String! # Can also be a reference to a User table, doesn't matter
  role: String!
}

В следующем примере реализации мутация UpdateMovieTitle включает поле query для получения данных из MoviePermission и следующие директивы для обеспечения безопасности и надежности операции:

  • Директива @transaction , гарантирующая, что все запросы авторизации и проверки завершаются или завершаются автоматически.
  • Директива @redact исключает результаты запроса из ответа. Это означает, что наша проверка авторизации выполняется на сервере Data Connect , но конфиденциальные данные не предоставляются клиенту.
  • Пара директив @check для оценки логики авторизации по результатам запроса, например проверки того, что данный идентификатор пользователя имеет соответствующую роль для внесения изменений.

mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query @redact {
    moviePermission( # Look up a join table called MoviePermission with a compound key.
      key: {movieId: $movieId, userId_expr: "auth.uid"}
    # Step 1a: Use @check to test if the user has any role associated with the movie
    # Here the `this` binding refers the lookup result, i.e. a MoviePermission object or null
    # The `this != null` expression could be omitted since rejecting on null is default behavior
    ) @check(expr: "this != null", message: "You do not have access to this movie") {
      # Step 1b: Check if the user has the editor role for the movie
      # Next we execute another @check; now `this` refers to the contents of the `role` field
      role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

Антипаттерны, которых следует избегать при авторизации

В предыдущем разделе описаны шаблоны, которым следует следовать при использовании директивы @auth .

Вы также должны знать о важных антипаттернах, которых следует избегать.

Избегайте передачи идентификаторов пользовательских атрибутов и параметров токена аутентификации в аргументах запроса и мутации.

Firebase Authentication — это мощный инструмент для представления потоков аутентификации и безопасного сбора данных аутентификации, таких как зарегистрированные идентификаторы пользователей и многочисленные поля, хранящиеся в токенах аутентификации.

Не рекомендуется передавать идентификаторы пользователей и данные токена аутентификации в аргументах запроса и мутации.

# Antipattern!
# This incorrectly allows any user to view any other user's posts
query AllMyPosts($userId: String!) @auth(level: USER) {
  posts(where: {authorUid: {eq: $userId}}) {
    id, text, createdAt
  }
}

Избегайте использования уровня доступа USER без каких-либо фильтров.

Как неоднократно обсуждалось в руководстве, основные уровни доступа, такие как USER , USER_ANON , USER_EMAIL_VERIFIED являются базовыми и отправными точками для проверок авторизации, которые необходимо улучшить с помощью фильтров и выражений. Использование этих уровней без соответствующего фильтра или выражения, проверяющего, какой пользователь выполняет запрос, по сути эквивалентно использованию уровня PUBLIC .

# Antipattern!
# This incorrectly allows any user to view all documents
query ListDocuments @auth(level: USER) {
  documents {
    id
    title
    text
  }
}

Избегайте использования уровня доступа PUBLIC или USER для прототипирования.

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

После того, как вы таким образом выполнили начальное прототипирование, начните переключаться с NO_ACCESS на готовую к использованию авторизацию с уровнями PUBLIC и USER . Однако не развертывайте их как PUBLIC или USER без добавления дополнительной логики, как показано в этом руководстве.

# Antipattern!
# This incorrectly allows anyone to delete any post
mutation DeletePost($id: UUID!) @auth(level: PUBLIC) {
  post: post_delete(
    id: $id,
  )
}

Используйте Firebase App Check для аттестации приложений.

Аутентификация и авторизация являются важнейшими компонентами безопасности Data Connect . Аутентификация и авторизация в сочетании с аттестацией приложений создают очень надежное решение для обеспечения безопасности.

При аттестации с помощью Firebase App Check устройства, на которых работает ваше приложение, будут использовать поставщика аттестации приложения или устройства, который подтверждает, что операции Data Connect происходят из вашего подлинного приложения, а запросы исходят от подлинного незащищенного устройства. Это подтверждение прилагается к каждому запросу, который ваше приложение отправляет в Data Connect .

Чтобы узнать, как включить App Check для Data Connect и включить его клиентский SDK в свое приложение, ознакомьтесь с обзором App Check .

Уровни аутентификации для директивы @auth(level)

В следующей таблице перечислены все стандартные уровни доступа и их эквиваленты CEL. Уровни аутентификации перечислены от широкого к узкому — каждый уровень охватывает всех пользователей, соответствующих следующим уровням.

Уровень Определение
PUBLIC Операцию может выполнить любой человек с аутентификацией или без нее.

Соображения: Данные могут быть прочитаны или изменены любым пользователем. Firebase рекомендует этот уровень авторизации для общедоступных данных, таких как списки продуктов или СМИ. См . примеры передового опыта и альтернативы .

Эквивалент @auth(expr: "true")

Фильтры и выражения @auth нельзя использовать в сочетании с этим уровнем доступа. Любое такое выражение завершится ошибкой 400 bad request.
USER_ANON Любой идентифицированный пользователь, включая тех, кто вошел в систему анонимно с помощью Firebase Authentication , имеет право выполнять запрос или мутацию.

Примечание. USER_ANON — это расширенный набор USER .

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

Поскольку потоки анонимного входа в Authentication выдают uid , уровень USER_ANON эквивалентен
@auth(expr: "auth.uid != nil")
USER Любой пользователь, вошедший в систему с помощью Firebase Authentication имеет право выполнять запрос или мутацию, за исключением анонимных пользователей, вошедших в систему.

Соображения: Обратите внимание, что вы должны тщательно разрабатывать запросы и изменения для этого уровня авторизации. Этот уровень только проверяет, вошел ли пользователь в систему с использованием Authentication , и не выполняет самостоятельно другие проверки, например, принадлежат ли данные пользователю. См . примеры передового опыта и альтернативы .

Эквивалентно @auth(expr: "auth.uid != nil && auth.token.firebase.sign_in_provider != 'anonymous'")"
USER_EMAIL_VERIFIED Любой пользователь, вошедший в систему с помощью Firebase Authentication с подтвержденным адресом электронной почты, имеет право выполнить запрос или мутацию.

Соображения: поскольку проверка электронной почты выполняется с использованием Authentication , она основана на более надежном методе Authentication , поэтому этот уровень обеспечивает дополнительную безопасность по сравнению с USER или USER_ANON . Этот уровень проверяет только то, что пользователь вошел в систему с использованием Authentication с подтвержденным адресом электронной почты, и самостоятельно не выполняет другие проверки, например, принадлежат ли данные пользователю. См . примеры передового опыта и альтернативы .

Эквивалентно @auth(expr: "auth.uid != nil && auth.token.email_verified")"
NO_ACCESS Эту операцию нельзя выполнить вне контекста Admin SDK.

Эквивалент @auth(expr: "false")

Справочник CEL для @auth(expr) и @check(expr)

Как показано в примерах в других разделах этого руководства, вы можете и должны использовать выражения, определенные в Common Expression Language (CEL), для управления авторизацией для Data Connect с помощью директив @auth(expr:) и @check .

В этом разделе рассматривается синтаксис CEL, относящийся к созданию выражений для этих директив.

Полная справочная информация по CEL представлена ​​в спецификации CEL .

Тестовые переменные, передаваемые в запросах и мутациях

Синтаксис @auth(expr) позволяет получать доступ и проверять переменные из запросов и мутаций.

Например, вы можете включить переменную операции, например $status , используя vars.status .

mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")

Данные, доступные для выражений

Оба выражения CEL @auth(expr:) и @check(expr:) могут оценивать следующее:

  • request.operationName
  • vars (псевдоним request.variables )
  • auth (псевдоним request.auth )

Кроме того, выражения @check(expr:) могут оценивать:

  • this (значение текущего поля)

Объект request.operationName

Объект request.operarationName хранит тип операции: запрос или мутацию.

Объект vars

Объект vars позволяет вашим выражениям получать доступ ко всем переменным, переданным в вашем запросе или мутации.

Вы можете использовать vars.<variablename> в выражении в качестве псевдонима для полного request.variables.<variablename> :

# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")

Объект auth

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

В ваших фильтрах и выражениях вы можете использовать auth в качестве псевдонима для request.auth .

Объект аутентификации содержит следующую информацию:

  • uid : уникальный идентификатор пользователя, назначенный запрашивающему пользователю.
  • token : Карта значений, собранных с помощью Authentication .

Более подробную информацию о содержимом auth.token см. в разделе Данные в токенах аутентификации.

this привязка

Привязка this оценивает поле, к которому прикреплена директива @check . В базовом случае вы можете оценить однозначные результаты запроса.

mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query @redact {
    moviePermission( # Look up a join table called MoviePermission with a compound key.
      key: {movieId: $movieId, userId_expr: "auth.uid"}
    ) {
      # Check if the user has the editor role for the movie. `this` is the string value of `role`.
      # If the parent moviePermission is null, the @check will also fail automatically.
      role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

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

Для любого заданного пути, если предок имеет значение null или [] , поле не будет достигнуто, и оценка CEL для этого пути будет пропущена. Другими словами, оценка происходит только тогда, когда this значение null или не null , но никогда не undefined .

Если само поле представляет собой список или объект, this имеет ту же структуру (включая всех выбранных потомков в случае объектов), как показано в следующем примере.

mutation UpdateMovieTitle2($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query {
    moviePermissions( # Now we query for a list of all matching MoviePermissions.
      where: {movieId: {eq: $movieId}, userId: {eq_expr: "auth.uid"}}
    # This time we execute the @check on the list, so `this` is the list of objects.
    # We can use the `.exists` macro to check if there is at least one matching entry.
    ) @check(expr: "this.exists(p, p.role == 'editor')", message: "You must be an editor of this movie to update title") {
      role
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

Синтаксис сложного выражения

Вы можете писать более сложные выражения, комбинируя их с && и || операторы.

mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")

В следующем разделе описаны все доступные операторы.

Операторы и приоритет операторов

Используйте следующую таблицу в качестве справочника по операторам и их соответствующему приоритету.

Даны произвольные выражения a и b , поле f и индекс i .

Оператор Описание Ассоциативность
a[i] a() af Индекс, вызов, доступ к полям слева направо
!a -a Унарное отрицание справа налево
a/ba%ba*b Мультипликативные операторы слева направо
a+b ab Аддитивные операторы слева направо
a>b a>=b a<b a<=b Реляционные операторы слева направо
a in b Наличие в списке или на карте слева направо
type(a) == t Сравнение типов, где t может быть bool, int, float, числом, строкой, списком, картой, меткой времени или длительностью. слева направо
a==ba!=b Операторы сравнения слева направо
a && b Условное И слева направо
a || b Условное ИЛИ слева направо
a ? true_value : false_value Тернарное выражение слева направо

Данные в токенах аутентификации

Объект auth.token может содержать следующие значения:

Поле Описание
email Адрес электронной почты, связанный с учетной записью, если таковой имеется.
email_verified true , если пользователь подтвердил, что у него есть доступ к адресу email . Некоторые провайдеры автоматически проверяют принадлежащие им адреса электронной почты.
phone_number Номер телефона, связанный с учетной записью, если он присутствует.
name Отображаемое имя пользователя, если оно установлено.
sub UID пользователя Firebase. Это уникально в рамках проекта.
firebase.identities Словарь всех идентификаторов, связанных с учетной записью этого пользователя. Ключами словаря могут быть любые из следующих: email , phone , google.com , facebook.com , github.com , twitter.com . Значения словаря представляют собой массивы уникальных идентификаторов для каждого поставщика удостоверений, связанного с учетной записью. Например, auth.token.firebase.identities["google.com"][0] содержит первый идентификатор пользователя Google, связанный с учетной записью.
firebase.sign_in_provider Поставщик входа, использованный для получения этого токена. Может быть одной из следующих строк: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com .
firebase.tenant TenantId, связанный с учетной записью, если он присутствует. Например, tenant2-m6tyz

Дополнительные поля в токенах идентификатора JWT

Вы также можете получить доступ к следующим полям auth.token :

Пользовательские заявки на токены
alg Алгоритм "RS256"
iss Эмитент Адрес электронной почты сервисного аккаунта вашего проекта
sub Предмет Адрес электронной почты сервисного аккаунта вашего проекта
aud Аудитория "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Выдано в срок Текущее время в секундах с начала эпохи UNIX.
exp Срок годности Время в секундах с начала эпохи UNIX, когда истекает срок действия токена. Это может быть максимум на 3600 секунд позже, чем iat .
Примечание: это контролирует только время истечения срока действия самого пользовательского токена . Но как только вы войдете в систему с помощью signInWithCustomToken() , они останутся в системе до тех пор, пока их сеанс не будет признан недействительным или пользователь не выйдет из системы.
<claims> (необязательно) Необязательные пользовательские утверждения для включения в токен, доступ к которым можно получить через auth.token (или request.auth.token ) в выражениях. Например, если вы создаете пользовательское утверждение adminClaim , вы можете получить к нему доступ с помощью auth.token.adminClaim .

Что дальше?