Какой общий алгоритм аутентификации с использованием JWT (JSON Web Token)?

Ответ

Алгоритм аутентификации с JWT представляет собой stateless-процесс, где токен сам содержит всю необходимую информацию для проверки подлинности и авторизации.

Типичный поток (алгоритм):

  1. Логин (Аутентификация):

    • Клиент отправляет учетные данные (логин/пароль) на защищенный эндпоинт (например, POST /auth/login).
    • Сервер проверяет учетные данные.
    • В случае успеха сервер генерирует JWT, подписывает его секретным ключом (алгоритмом, например, HS256) или приватным ключом (RS256) и отправляет клиенту.
      // Пример payload (полезной нагрузки) JWT
      {
      "sub": "user123",
      "name": "John Doe",
      "roles": ["USER", "EDITOR"],
      "iat": 1516239022,
      "exp": 1516242622 // Токен истекает через 1 час
      }
  2. Использование токена (Авторизация):

    • Клиент сохраняет JWT (обычно в localStorage или HttpOnly cookie).
    • При каждом последующем запросе к защищенному API клиент включает JWT в заголовок Authorization:
      GET /api/protected-resource HTTP/1.1
      Authorization: Bearer <ваш.jwt.токен>
  3. Верификация токена (на сервере):

    • Сервер извлекает токен из заголовка.
    • Проверяет подпись токена, используя секретный/публичный ключ, чтобы убедиться, что токен не был изменен.
    • Проверяет claims (утверждения):
      • exp (expiration time) – не истек ли срок действия.
      • iss (issuer) – выпущен ли доверенным издателем.
      • aud (audience) – предназначен ли для данного приложения.
    • Если проверки пройдены, сервер извлекает данные пользователя (например, sub, roles) из payload токена и использует их для авторизации доступа к ресурсу. Нет необходимости запрашивать базу данных или сессию.

Ключевые преимущества:

  • Stateless: Серверу не нужно хранить сессию, что упрощает масштабирование.
  • Самоописываемость: Токен содержит все необходимые данные.
  • Универсальность: Легко используется между различными сервисами (микросервисами, мобильными клиентами).

Важные меры безопасности:

  • Всегда используйте HTTPS.
  • Устанавливайте короткое время жизни (exp) токена.
  • Для обновления токенов используйте отдельный refresh token, хранящийся более безопасно.

Ответ 18+ 🔞

Давай разберём эту вашу JWT-авторизацию, а то некоторые думают, что это какая-то магия, а на деле — просто хитрая бумажка, которую нужно правильно проверить, чтобы тебя не наебали.

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

Как это всё работает, по шагам:

  1. Ты заходишь в клуб (Логин). Ты шлёшь свои креды (логин/пароль) на /auth/login. Сервер смотрит: «А, Вася, знакомый мудила». Вместо того чтобы заводить на тебя целое досье в своей памяти (сессию), он хватает штампик и ставит тебе на руку JWT. Внутри штампа написано, кто ты и что тебе можно.

    // Вот что вписано в твой штамп (payload)
    {
      "sub": "user123", // Кто ты (subject)
      "name": "Вася Пупкин",
      "roles": ["USER", "EDITOR"], // Что тебе дозволено
      "iat": 1516239022, // Когда выдан (issued at)
      "exp": 1516242622 // Когда просрочится и станет хуёвым
    }

    Главное — этот штамп подписан секретным ключом сервера. Подделать его снаружи — та ещё задача, если, конечно, ключ не лежит в публичном репозитории на гитхабе, что бывает сплошь и рядом.

  2. Ты шатаешься по клубу (Делаешь запросы). Сохранил ты этот JWT у себя (в localStorage или в куке). Теперь, когда тебе нужно заказать виски на барной стойке (запрос к /api/order), ты просто показываешь свою руку с печатью. В мире HTTP это выглядит так:

    GET /api/order/whisky HTTP/1.1
    Authorization: Bearer <твой.тут.токен>

    «Bearer» — это «предъявитель». То есть, у кого этот токен, тот и есть Вася, по умолчанию.

  3. Вышибала проверяет печать (Верификация на сервере). Вот тут вся соль. Сервер, получив твой токен, не бежит в базу данных. Он делает три вещи:

    • Смотрит, не подделка ли? Проверяет подпись тем самым секретным ключом. Если подпись не совпадает — всё, пиздец, токен фейковый, в ебло и на выход.
    • Смотрит, не просрочен ли? Сверяет текущее время с полем exp. Если срок вышел — твой штамп недействителен, иди обновляй.
    • Может, ещё че проверить? Иногда глядит на iss (кто выдал) и aud (для кого выдавали), но это уже тонкости.

    Если всё чисто — сервер верит написанному внутри токена. Он вытаскивает оттуда sub: "user123" и roles: ["USER", "EDITOR"] и решает, дать тебе виски или только квас.

И в чём же, блядь, профит?

  • Серверу похуй (Stateless). Ему не нужно помнить миллион активных сессий. Получил токен, проверил подпись — и всё. Масштабируется нахуй легко: хоть двадцать серверов поставь, им не нужно синхронизировать между собой сессии.
  • Всё написано внутри. Не надо каждый раз лезть в базу за ролями пользователя. Быстро, ёпта.
  • Универсальная хуйня. Мобильному приложению дал, фронтенду дал, другому микросервису дал — все понимают этот формат.

Но предупреждаю, ебанаты!

  • Только по HTTPS! Если пускать токен по открытому каналу — его могут спиздить и пользоваться, как своим. Это как сфоткать твою печать и прилепить себе на руку.
  • Делай жизнь токена короткой! exp — твой лучший друг. Выдал доступ на 15-30 минут. Если украдут — быстро сдохнет.
  • Используй Refresh Token! Чтобы пользователь не вводил логин-пароль каждые 15 минут, выдай ему вторую, долгоживущую бумажку — refresh token. Он хранится максимально безопасно (в HttpOnly куке, идеально). Им можно будет получить новый JWT, когда старый сдох. Но если и refresh token спиздят — это уже полный пиздец, потому что вор получит доступ на долго.