Назад в блог
Веб-разработка

Вход через Google на сайте: OAuth и SSO

Как добавить вход через Google на сайт или в приложение? Схема OAuth 2.0 и OpenID Connect, проверка ID-токена, связывание аккаунтов, корпоративный SSO (Google Workspace, Microsoft Entra), чек-лист безопасности и выбор между готовым сервисом и собственной реализацией.

Google ile GirişOAuthSSOKimlik DoğrulamaNext.js

Вход через Google добавляется на сайт или в приложение с помощью OAuth 2.0 и его слоя идентификации OpenID Connect (OIDC). Коротко: пользователь перенаправляется в Google, Google проверяет личность и отправляет вашему сайту подписанный ID-токен; ваш сервер проверяет подпись и получателя токена, сопоставляет пользователя со своими записями и открывает собственную сессию. Ваш сайт никогда не видит и не хранит пароль от Google. Техническая настройка занимает немного времени; проект растягивают связывание аккаунтов, управление сессиями и требования корпоративных клиентов к единому входу (SSO). В этой статье описана схема, которую мы применяем в корпоративных веб-проектах; это часть нашей услуги разработки сайтов, отвечающая за аутентификацию.

OAuth, OpenID Connect и SSO: что есть что

В обиходе эти три термина используют как синонимы, но они отвечают на три разных вопроса. OAuth 2.0 протокол делегирования прав: он говорит «это приложение может читать мой календарь от моего имени», но не говорит, кто вы. OpenID Connect слой идентификации поверх OAuth: подписанный ID-токен сообщает «этот пользователь имеет такую-то идентичность, его почта подтверждена». Вход через Google на практике и есть OpenID Connect. SSO (single sign-on) архитектурная цель: пользователь входит один раз и получает доступ к нескольким приложениям без повторного ввода пароля. Потребности бывают двух видов:

  • Социальный вход (B2C): ваши клиенты регистрируются и входят через аккаунт Google, Apple или Microsoft. Цель снизить трение и не брать на себя управление паролями.
  • Корпоративный SSO (B2B / внутренние приложения): сотрудники входят через провайдера идентификации компании (Google Workspace, Microsoft Entra ID, Keycloak). Цель централизованное управление доступом: при увольнении доступ отключается в одном месте.

Оба варианта используют один протокол, но продуктовые решения различаются. При социальном входе провайдера выбирает пользователь; при корпоративном SSO провайдера задаёт компания-клиент и обычно хочет подключить собственного арендатора через SAML или OIDC.

Схема входа через Google по шагам

Рекомендуемая схема «authorization code с PKCE». Старый implicit flow, выдававший токены в браузере, больше не рекомендуется; токены всегда получает сервер, а браузеру достаётся только ваш собственный cookie сессии.

  • В Google Cloud Console создаётся OAuth-клиент; разрешённые адреса возврата (redirect URI) регистрируются с точным совпадением, без масок.
  • Когда пользователь нажимает «Войти через Google», сервер генерирует случайный state и PKCE code_verifier, сохраняет их в короткоживущем cookie и перенаправляет пользователя на адрес авторизации Google.
  • Google проверяет личность, показывает пользователю, какие данные будут переданы, и запрашивает согласие; браузер возвращается на ваш callback-адрес с параметром code.
  • Сервер сверяет state с cookie и обменивает code на ID-токен на token-эндпоинте Google (с client_secret и code_verifier).
  • Подпись ID-токена проверяется по опубликованным ключам Google вместе с полями iss, aud и сроком действия; почта должна быть отмечена как подтверждённая.
  • Пользователь находится или создаётся в базе, ваш cookie сессии завершает вход. Токен Google в браузер не передаётся.

Пример: callback как route handler в Next.js

// app/api/auth/google/callback/route.ts
import { createRemoteJWKSet, jwtVerify } from 'jose';

const GOOGLE_JWKS = createRemoteJWKSet(
  new URL('https://www.googleapis.com/oauth2/v3/certs'),
);

export async function GET(req: Request) {
  const url = new URL(req.url);
  const code = url.searchParams.get('code');
  const state = url.searchParams.get('state');

  // state записан в cookie при старте входа: защита от CSRF
  if (!code || !state || state !== await readStateCookie()) {
    return new Response('Недопустимый запрос', { status: 400 });
  }

  // обмен code -> токен всегда выполняется на сервере
  const tokenRes = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      code,
      grant_type: 'authorization_code',
      client_id: process.env.GOOGLE_CLIENT_ID!,
      client_secret: process.env.GOOGLE_CLIENT_SECRET!,
      redirect_uri: process.env.GOOGLE_REDIRECT_URI!,
      code_verifier: await readVerifierCookie(),
    }),
  });
  const { id_token } = (await tokenRes.json()) as { id_token: string };

  // проверка подписи, издателя, получателя и срока
  const { payload } = await jwtVerify(id_token, GOOGLE_JWKS, {
    issuer: ['https://accounts.google.com', 'accounts.google.com'],
    audience: process.env.GOOGLE_CLIENT_ID,
  });
  if (payload.email_verified !== true) {
    return new Response('Почта не подтверждена', { status: 403 });
  }

  // идентичность это постоянный "sub" от Google, а не адрес почты
  const user = await findOrLinkUser({
    provider: 'google',
    subject: payload.sub!,
    email: String(payload.email),
  });

  return createSessionAndRedirect(user.id, '/dashboard');
}

Связывание аккаунтов: где проекты застревают

На большинстве сайтов, добавляющих вход через Google, уже есть пользователи с почтой и паролем. Если заранее не решить, что произойдёт, когда тот же человек войдёт через Google, появятся либо два отдельных аккаунта, либо будут объединены не те. Проблему решают три правила. Первое: идентичность пользователя не адрес почты, а постоянное значение sub, которое присылает Google; почта меняется, sub нет. Второе: автоматическое объединение с существующим аккаунтом выполняется только если Google подтвердил почту; иначе войти сможет аккаунт, выдающий чужой адрес за свой. Третье: пользователь должен иметь возможность привязать несколько провайдеров, поэтому данные провайдера хранятся в отдельной таблице «идентичности» (пользователь, провайдер, sub), а не в колонках таблицы пользователей.

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

Корпоративный SSO: Google Workspace и Microsoft Entra

Когда SSO нужен для B2B-продукта или внутренней панели, задача вырастает на несколько шагов. Нужно ограничить, какие домены могут входить: поле hd в ID-токене Google содержит домен Workspace пользователя, но это только проверка, а не замена авторизации. Если пользователи создаются автоматически при первом входе (just-in-time provisioning), должна быть определена стартовая роль; проектирование ролей мы описали в статье о ролях пользователей и авторизации. Если подключается Microsoft Entra или другой арендатор, клиент обычно регистрирует ваше приложение на своей стороне через SAML или OIDC, а вы храните отдельного издателя и набор ключей для каждого клиента. Чаще всего забывают о выходе: когда сотрудник увольняется, его аккаунт у провайдера закрывается, но ваша открытая сессия живёт до собственного истечения. Делайте сессии короткими или обрабатывайте уведомление провайдера о выходе.

Чек-лист безопасности

  • state и PKCE обязательны в каждом запросе; state одноразовый и сверяется с cookie при callback.
  • Redirect URI зарегистрированы с точным совпадением; для теста и продакшена используются отдельные клиенты, а client_secret никогда не попадает в браузер или мобильную сборку.
  • ID-токен используется только для идентификации; вызовы API авторизует ваша собственная сессия или выданный вами токен. Отправлять ID-токен другим сервисам как ключ доступа распространённая ошибка.
  • Scope минимальны: openid, email и profile достаточно для большинства сайтов. Доступ к календарю или Drive при необходимости запрашивается отдельно и позже.
  • Путь восстановления для пользователя, потерявшего аккаунт Google, проектируется заранее: одноразовая ссылка на почту или второй провайдер. Аккаунты, привязанные к одному провайдеру, самый частый источник обращений в поддержку.
  • На эндпоинты входа ставится ограничение частоты, неудачные попытки логируются; остальные поверхности атаки разобраны в статье о безопасности сайта.

Для рискованных действий (подтверждение платежа, изменение прав) одного входа через Google недостаточно; запрашивайте второе подтверждение в момент действия. Эту сторону мы разобрали в статье о SMS OTP-верификации.

Готовый сервис идентификации или своя реализация?

Облачные сервисы вроде Auth0, Firebase Authentication и Clerk, а также самостоятельно размещаемые продукты вроде Keycloak дают всю эту схему, сброс пароля и многофакторную аутентификацию из коробки. Для одного провайдера и простой модели пользователей достаточно собственной реализации с библиотекой вроде Auth.js, и данные пользователей остаются в вашей базе. Если одновременно нужны мультиарендный SSO, поддержка SAML, многофакторная аутентификация и журналы аудита, готовый сервис или Keycloak сокращают проект на недели. Решают два вопроса: где будут храниться данные пользователей и можно ли при уходе из сервиса экспортировать пользователей вместе с хешами паролей? Если таблица пользователей в вашей базе, второй вопрос решается сам собой; этот подход согласуется и с мультиарендной моделью из статьи о разработке SaaS-продукта.

Замечание о персональных данных

При входе через Google вам передаются имя, почта и фото профиля; это персональные данные, и в политике конфиденциальности должны быть указаны их источник (провайдер идентификации) и цель обработки. Запрашивайте только то, что нужно для входа, и не храните фото профиля, если оно не используется. Турецкий правовой контекст описан в статье о сайте, соответствующем KVKK; этот текст не является юридической консультацией.

Вывод

При правильной реализации вход через Google даёт пользователям регистрацию без трения, а вашему сайту избавление от хранения паролей. Техническая схема стандартна; проект определяют правила связывания аккаунтов, срок жизни сессии и ожидания корпоративных клиентов по SSO. Если вы хотите добавить социальный вход или корпоративный SSO на существующий сайт, отправьте требования через форму запроса, и мы спланируем схему вместе с вашей текущей таблицей пользователей.

Let's Build Your Project

Get a free consultation for your website, mobile app, or corporate software project.

Get a Free QuoteExplore our Web Development service