JS: Веб-разработка

Теория: Сессия

Сессия – это абстракция, созданная для удобной работы с индивидуальными пользователями. Она используется для идентификации пользователей и позволяет отличать их друг от друга. Например, аутентификация на сайтах построена поверх механизма сессии. В этом уроке мы обсудим сессии в контексте JavaScript.

Как работают сессии

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

Cookie: JSESSIONID=node01lywaspcyuggy15sok9tw6q9eh0.node0

Для работы с сессиями в Fastify нужно подключить пакет:

npm i @fastify/session

При подключении нужно указать секретный ключ из 32 символов.

Принцип работы с данными сессии очень похож на то, как идет работа с куками. Мы можем добавить данные в сессию и прочитать их:

app.get('/increment', (req, res) => {
  req.session.counter = req.session.counter || 0
  req.session.counter += 1
})

Добавленные данные хранятся в сессии до тех пор, пока не произойдет одно из следующих событий:

  • Кука будет удалена
  • Закончится время жизни куки
  • Данные сессии будут удалены на бэкенде

Как использовать сессии

Реализуем упрощенный пример аутентификации на сайте.

Аутентификация это процедура проверки подлинности, например:

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

Аутентификацию не следует путать с авторизацией (процедурой предоставления субъекту определённых прав) и идентификацией (процедурой распознавания субъекта по его идентификатору).

Разберем пример:

import encrypt from './encrypt.js'

app.post('/session', (req, res) => {
  // ...
  if (user.passwordDigest === encrypt(password)) {
    req.session.userId = user.id
    // ...
  }
  // ...
})

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

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

// encrypt.js
import crypto from 'crypto'

export default (text) => {
  const hash = crypto.createHmac('sha512', 'salt')
  hash.update(text)
  return hash.digest('hex')
}

Завершено

0 / 23