Поиск по сайту:

Как использовать веб-токены JSON (JWT) в Express.js


Введение

Веб-токены JSON (JWT) поддерживают авторизацию и обмен информацией.

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

Предупреждение: имейте в виду риск безопасности при хранении JWT в localStorage.

В этой статье вы узнаете о приложениях JWT в отношениях сервер-клиент с использованием Node.js и ванильного JavaScript.

Предпосылки

Чтобы следовать этой статье, на вашем компьютере должны быть установлены следующие компоненты:

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

Шаг 1 — Генерация токена

jsonwebtoken — это реализация веб-токенов JSON.

Вы можете добавить его в свой проект JavaScript, выполнив в терминале следующую команду:

  1. npm install jsonwebtoken

И импортируйте его в свои файлы следующим образом:

const jwt = require('jsonwebtoken');

Чтобы подписать токен, вам нужно будет иметь 3 части информации:

  1. Секрет токена
  2. Фрагмент данных для хеширования в токене.
  3. Срок действия токена

секрет токена – это длинная случайная строка, используемая для шифрования и расшифровки данных.

Один из вариантов создания этого секрета — использовать встроенную в Node.js библиотеку crypto, например:

> require('crypto').randomBytes(64).toString('hex')
// '09f26e402586e2faa8da4c98a35f1b20d6b033c6097befa8be3486a829587fe2f90a832bd3ff9d42710a4da095a2ce285b009f0c3730cd9b8e1af3eb84df6611'

Предупреждение: будьте осторожны! Если ваш секрет прост, процесс проверки токена будет намного проще взломать неавторизованным злоумышленником.

Теперь сохраните этот секрет в файле .env вашего проекта:

TOKEN_SECRET=09f26e402586e2faa8da4c98a35f1b20d6b033c60...

Чтобы перенести этот токен в файл Node.js и использовать его, вам нужно использовать dotenv:

  1. npm install dotenv

И импортируйте его в свои файлы следующим образом:

const dotenv = require('dotenv');

// get config vars
dotenv.config();

// access config var
process.env.TOKEN_SECRET;

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

Время истечения срока действия токена – это строка, например 1800 секунд (30 минут), в которой указано, через какое время токен станет недействительным.

Вот пример функции для подписи токенов:

function generateAccessToken(username) {
  return jwt.sign(username, process.env.TOKEN_SECRET, { expiresIn: '1800s' });
}

Это может быть отправлено обратно из запроса на вход или вход пользователя:

app.post('/api/createNewUser', (req, res) => {
  // ...

  const token = generateAccessToken({ username: req.body.username });
  res.json(token);

  // ...
});

В этом примере значение username берется из req (request). И предоставляет токен в виде res (response).

На этом можно сделать вывод о том, как jsonwebtoken, crypto и dotenv можно использовать для создания JWT.

Шаг 2 — Аутентификация токена

Существует множество способов реализации системы аутентификации JWT в приложении Express.js.

Один из подходов заключается в использовании функций промежуточного программного обеспечения в Express.js.

Как это работает, когда делается запрос к определенному маршруту, вы можете отправить переменные (req, res) в промежуточную функцию до той, которая указана в app.get(( req, res) => {}).

Промежуточное программное обеспечение — это функция, которая принимает параметры (req, res, next).

  • req — это отправленный запрос (GET, POST, DELETE, PUT и т. д.).
  • res — это ответ, который можно отправить обратно пользователю множеством способов (res.sendStatus(200), res.json( ) и т. д.).
  • next — это функция, которую можно вызвать, чтобы переместить выполнение за часть промежуточного программного обеспечения в фактический ответ сервера app.get.

Вот пример промежуточной функции для аутентификации:

const jwt = require('jsonwebtoken');

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization']
  const token = authHeader && authHeader.split(' ')[1]

  if (token == null) return res.sendStatus(401)

  jwt.verify(token, process.env.TOKEN_SECRET as string, (err: any, user: any) => {
    console.log(err)

    if (err) return res.sendStatus(403)

    req.user = user

    next()
  })
}

Пример запроса с использованием этой промежуточной функции будет выглядеть примерно так:

GET https://example.com:4000/api/userOrders
Authorization: Bearer JWT_ACCESS_TOKEN

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

app.get('/api/userOrders', authenticateToken, (req, res) => {
  // executes after authenticateToken
  // ...
})

Этот код будет аутентифицировать токен, предоставленный клиентом. Если он действителен, он может перейти к запросу. Если он недействителен, это может быть обработано как ошибка.

Шаг 3 — Обработка токенов на стороне клиента

Когда клиент получает токен, он часто хочет сохранить его для сбора информации о пользователе в будущих запросах.

Самый популярный способ хранения токенов аутентификации — файл cookie HttpOnly.

Вот реализация хранения куки с использованием кода JavaScript на стороне клиента:

// get token from fetch request
const token = await res.json();

// set token in cookie
document.cookie = `token=${token}`

Этот подход сохраняет ответы локально, где на них можно ссылаться для будущих запросов к серверу.

На этом завершается процесс запроса токена, создания токена, получения токена, передачи токена с новыми запросами и проверки токена.

Заключение

В этой статье вы познакомились с JWT и одним из подходов к их применению в приложении Node.js. Этот подход основывался на сочетании jsonwebtoken, crypto, dotenv и express.

Еще один подход к использованию JWT — как реализовать аутентификацию API с помощью веб-токенов и паспорта JSON.

Дополнительные сведения о JWT см. в документации «Введение».

Если вы хотите узнать больше о Node.js, посетите нашу тематическую страницу Node.js, где вы найдете упражнения и проекты по программированию.