Простая система авторизации с использованием JWT

В продолжение предыдущего поста я попытаюсь реализовать систему авторизации с помощью JWT (Json Web Token) для моей многопользовательской игры TicTacToe.

Живой сайт
Исходный код

Что такое JWT

JWT — это авторизационный токен, создаваемый в бэкенде, передаваемый во фронтенд, после чего фронтенд может отправлять этот токен вместе с запросами на доступ к защищенным маршрутам API, это делается для того, чтобы убедиться, что запрос от пользователя X действительно сделан самим пользователем X. Обычно JWT-токен создается со сроком действия.

Здесь есть обратная сторона использования JWT: каждый токен, который был создан и срок действия которого еще не истек, все еще может быть использован для доступа к защищенным маршрутам API. А это обычно не то, чего вы хотели.

Здесь следует сделать небольшую оговорку: Я думаю, что JWT сам по себе очень прост, но его правильная реализация — это самая сложная часть, поэтому если вы знаете лучший способ или у вас есть исправления, пожалуйста, дайте мне знать! Спасибо.

Метод аннулирования JWT

Итак, чтобы аннулировать и ограничить доступ к токену, из того, что я нашел, есть в основном 2 метода:

  1. Занести токен в черный список/белый список.
  2. Использовать секретный ключ пользователя для токена.

Честно говоря, я все еще не знаю плюсы/минусы этих методов, но я собираюсь использовать второй.

Создание персонального ключа пользователя

примечание: все приведенные примеры являются упрощенной версией

const bcrypt = require('bcrypt');

function generatePersonalKey() {
  return bcrypt.genSaltSync(10);
}
Вход в полноэкранный режим Выход из полноэкранного режима

Сначала личный ключ, нам нужно создать функцию для генерации ключей, например, случайных строк, чисел или чего угодно. Но здесь я создал generatePersonalKey(), используя пакеты bcrypt для создания случайной соли.

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  username: String,
  password: String,
  personalKey: String,
});
Вход в полноэкранный режим Выход из полноэкранного режима

А в моем UserSchema (mongoose), например, мы просто инициализируем personalKey при создании пользователя. А когда пользователь выходит из системы, мы просто регенерируем personalKey, таким образом, токены до этого всегда будут недействительны, потому что они использовали другой ключ.

Создание JWT

const jwt = require('jsonwebtoken');

const payload = { username: 'khusyasy' };
const token =
  jwt.sign(payload, user.personalKey, {
    expiresIn: '1h',
  });
Вход в полноэкранный режим Выход из полноэкранного режима

Для создания самого токена я использовал пакет jsonwebtoken. На самом деле все очень просто, как показано в примере выше. После этого мы устанавливаем в cookies ответа флаг httpOnly, чтобы токен нельзя было установить/получить с помощью javascript в браузере.

Проверка авторизации

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

Оказывается, можно… просто используя decode для чтения полезной нагрузки и получения персонального ключа пользователя, а затем используя персональный ключ для проверки самого токена. Например:

const payload = jwt.decode(token);

const user = await User.findOne({ username: payload.username });

try {
  const verified = jwt.verify(token, user.personalKey);
  // token is verified
} catch (err) {
  // token is invalid
}
Войти в полноэкранный режим Выход из полноэкранного режима

На сегодня это все, спасибо за чтение!

используемые пакеты:

  • bcrypt
  • jsonwebtoken
  • mongoose

Оцените статью
devanswers.ru
Добавить комментарий