Авторизация для начинающих разработчиков: Email/пароль, OAuth, OTP и JWT — полный гайд 2026

Разбираем все способы авторизации современных веб-приложений: от классического email/пароль до "Войти через Google" и SMS-кодов. Понятные объяснения, примеры кода, частые ошибки и чек-лист для собеседования — всё, что нужно знать junior разработчику о JWT, OAuth 2.0 и одноразовых паролях.

Mobile Разработка

6 мин

Помню, как год назад смотрел на страницу логина крупного проекта и думал: «Боже, как же это всё работает?» Четыре кнопки для входа, какие-то токены, редиректы... Голова кругом. Сегодня разберём всё по полочкам, чтобы ты не утонул в этом море технологий.

Почему авторизация — это не просто «введи пароль» 🔐

В 2026 году пользователи хотят входить в приложения быстро, безопасно и без головной боли. Одни предпочитают классический email и пароль, другие — одну кнопку «Войти через Google», третьи вообще хотят получить код в SMS и не заморачиваться с паролями.

Твоя задача как разработчика — дать им всё это, причём так, чтобы система была безопасной и не превратилась в спагетти-код 🍝

Давай начнём с базы, которую должен понимать каждый junior, а потом пойдём дальше.

Email/пароль: старая школа, которая никуда не делась ✉️

Классическая авторизация через email и пароль — это фундамент. Да, многие говорят, что она устарела, но правда в том, что её всё ещё используют миллионы сервисов. И знать, как она работает правильно, критически важно.

Что происходит при регистрации

Пользователь вводит email и пароль. Твоя первая задача — валидация. Email должен быть настоящим (хотя бы синтаксически корректным), а пароль — достаточно сложным.

В 2026 минимум — 8 символов, буквы разного регистра, цифры, спецсимволы. Но требования зависят от проекта — не везде нужен «пароль как от сейфа банка».

Дальше самое важное: никогда, слышишь, НИКОГДА не храни пароли в открытом виде. Ты должен захешировать пароль перед сохранением в базу данных. В 2026 стандарт — bcrypt или Argon2.

// Пример с bcrypt (Node.js)
const bcrypt = require('bcrypt');

// При регистрации
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(userPassword, saltRounds);
// Сохраняем hashedPassword в базу

// При входе
const isValid = await bcrypt.compare(userPassword, hashedPasswordFromDB);
if (isValid) {
  // Пользователь авторизован
}

Что происходит при входе

Пользователь вводит email и пароль. Ты ищешь этот email в базе, достаёшь хеш пароля и сравниваешь его с введённым паролем через bcrypt.compare. Если совпало — генеришь токен (обычно JWT) и отдаёшь клиенту.

JWT — твой новый лучший друг 🤝

JSON Web Token — это строка, которая содержит зашифрованную информацию о пользователе. После успешной авторизации ты создаёшь JWT с данными пользователя (id, email, роль) и отправляешь клиенту. Клиент сохраняет токен и отправляет его с каждым запросом к API.

const jwt = require('jsonwebtoken');

// Создание токена
const token = jwt.sign(
  { userId: user.id, email: user.email },
  process.env.JWT_SECRET,
  { expiresIn: '7d' }
);

// Проверка токена
const decoded = jwt.verify(token, process.env.JWT_SECRET);

Refresh токены: когда access token протух 🧊

Access токен обычно живёт недолго — от 15 минут до нескольких часов. Когда он истекает, пользователь не должен заново вводить пароль. Для этого используется refresh token — долгоживущий токен, который хранится в безопасном месте (обычно httpOnly cookie) и используется для получения нового access token.

Логика простая: короткий токен для работы, длинный токен для обновления короткого. Этот паттерн ты встретишь в большинстве реальных проектов.

OAuth 2.0: «Войти через Google» и вся эта магия ✨

Когда пользователь нажимает «Войти через Google» или «Войти через Apple», за кулисами происходит танец по протоколу OAuth 2.0. Это стандарт, который позволяет сторонним сервисам авторизовать пользователей без передачи пароля.

Как это работает в двух словах

  1. Пользователь кликает «Войти через Google»

  2. Ты редиректишь его на страницу Google

  3. Пользователь логинится и даёт разрешение

  4. Google редиректит обратно на твой сайт с временным code

  5. Ты меняешь code на токен и получаешь данные пользователя

Что нужно знать junior’у

  • Нужно зарегистрировать приложение в консоли (Google/Apple) и получить Client ID и Client Secret.

  • Самый популярный сценарий — Authorization Code Flow.

  • Не теряй состояние между редиректами — используй параметр state (защита от CSRF).

  • Client Secret никогда не должен попадать на фронтенд.

// Пример с Passport.js (Node.js)
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;

passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: "http://localhost:3000/auth/google/callback"
  },
  async (accessToken, refreshToken, profile, done) => {
    // Здесь ты получаешь данные пользователя
    // Ищешь его в своей базе или создаёшь нового
    const user = await findOrCreateUser(profile);
    return done(null, user);
  }
));

Apple Sign In: особенности 🍏

Apple серьёзно относится к приватности. Они могут скрыть настоящий email пользователя и дать прокси-email вида randomstring@privaterelay.appleid.com. Плюс у них есть своя специфика с генерацией client_secret — он создаётся программно, а не просто выдаётся в консоли.

Главные грабли: неправильный redirect_uri (должен совпадать 1 в 1), отсутствие state, не обработан “user cancelled”, и утечка Client Secret на фронт.

OTP: одноразовые пароли и SMS-коды 📲

One-Time Password — код, который живёт несколько минут и используется один раз. В 2026 это один из самых популярных способов авторизации, особенно в мобильных приложениях.

Как это работает

  1. Пользователь вводит номер телефона

  2. Ты генеришь код (4–6 цифр), сохраняешь с TTL (часто в Redis)

  3. Отправляешь код через SMS-шлюз

  4. Пользователь вводит код → ты проверяешь → создаёшь сессию

// Генерация OTP
function generateOTP(length = 6) {
  const digits = '0123456789';
  let otp = '';
  for (let i = 0; i < length; i++) {
    otp += digits[Math.floor(Math.random() * 10)];
  }
  return otp;
}

// Сохранение с TTL (Redis)
await redis.setex(`otp:${phoneNumber}`, 300, otp); // 5 минут

// Отправка SMS
await smsService.send(phoneNumber, `Ваш код: ${otp}`);

// Проверка
const storedOTP = await redis.get(`otp:${phoneNumber}`);
if (storedOTP === userInputOTP) {
  // Авторизация успешна
  await redis.del(`otp:${phoneNumber}`);
}

TOTP: когда SMS — не вариант ⏱️

Time-based One-Time Password — коды, которые генерируются приложениями типа Google Authenticator или Authy. Работает на основе секретного ключа и времени. Отличный вариант для 2FA.

const speakeasy = require('speakeasy');

// Генерация секрета
const secret = speakeasy.generateSecret({ name: 'MyApp (user@email.com)' });
// secret.base32 — это то, что нужно сохранить в базе

// Проверка кода
const verified = speakeasy.totp.verify({
  secret: secret.base32,
  encoding: 'base32',
  token: userInputCode,
  window: 2 // допуск на несинхронизацию времени
});

Безопасность OTP

  • Ограничивай количество попыток ввода (обычно 3–5)

  • Используй rate limiting (не больше N SMS на номер в час)

  • Делай коды достаточно длинными (минимум 6 цифр)

  • Обязательно ставь TTL (5–10 минут)

Здесь хорошо зайдёт иллюстрация «карта авторизации» — чтобы визуально собрать всё в одну картинку: email/пароль → JWT → refresh → OAuth → OTP.

Что должен знать junior: чек-лист для собеседования 🧠

Базовые вещи

  • Разница между authentication и authorization

  • Что такое JWT и из каких частей он состоит (Header, Payload, Signature)

  • Почему нельзя хранить пароли в открытом виде

  • Что такое соль в хешировании паролей

Средний уровень

  • Access token vs refresh token

  • Как OAuth 2.0 работает на высоком уровне

  • Что такое CSRF и защита через state/token/origin

  • Где хранить токены на фронте и почему (httpOnly cookies / memory / localStorage)

Продвинутый уровень

  • Logout при JWT (blacklist в Redis или короткий TTL)

  • PKCE в OAuth и зачем он нужен

  • Защита от брутфорса при OTP (rate limiting, backoff, captcha)

В 2026 это уже не ракетная наука 🚀

Ещё 5–10 лет назад OAuth казался чем-то недоступным. Сейчас это стандарт, который встроен во все нормальные фреймворки. Библиотеки делают 80% работы, а от тебя требуется понимание концепций и умение правильно всё склеить.

Начни с базы — email/пароль и JWT. Потом добавляй OAuth. И если нужно — OTP для удобства или дополнительной безопасности. Всегда помни про минимум: хешируй пароли, проверяй токены, ограничивай попытки входа, используй HTTPS.

Всё это и намного больше можно изучить в Кодике 🎓

Если после прочтения этой статьи у тебя появились вопросы (а они точно появились — авторизация глубокая тема), приходи в Кодик.

Кодик — обучение программированию с упором на практику: мы разбираем темы подробно, с живыми примерами кода и объяснениями подводных камней. Не «вот код, скопируй», а понимание того, как и почему всё работает.

  • Практические задания: соберёшь авторизацию с нуля — от email/пароль до OAuth и 2FA

  • Закрепление навыков через упражнения и мини-проекты

  • Разбор типовых ошибок и паттернов из реальных приложений

Нужна поддержка? Есть комьюнити 👥

У нас активный Telegram-канал, где сидит больше 2000 разработчиков. Можно задать вопрос, обсудить проблему, попросить ревью кода или просто пообщаться с людьми на том же пути.

Присоединяйся к Кодику — разберём авторизацию так, что ты сможешь объяснять её другим с закрытыми глазами 😉

Комментарии