Как использовать веб-токены JSON (JWT) в Express.js
Введение
Веб-токены JSON (JWT) поддерживают авторизацию и обмен информацией.
Одним из распространенных вариантов использования является предоставление клиентам возможности сохранять информацию о сеансе после входа в систему. Сохраняя информацию о сеансе локально и передавая ее на сервер для проверки подлинности при выполнении запросов, сервер может доверять тому, что клиент является зарегистрированным пользователем.
Предупреждение: имейте в виду риск безопасности при хранении JWT в localStorage.
В этой статье вы узнаете о приложениях JWT в отношениях сервер-клиент с использованием Node.js и ванильного JavaScript.
Предпосылки
Чтобы следовать этой статье, на вашем компьютере должны быть установлены следующие компоненты:
- Node.js установлен локально, что можно сделать, следуя инструкциям по установке Node.js и созданию локальной среды разработки.
Шаг 1 — Генерация токена
jsonwebtoken
— это реализация веб-токенов JSON.
Вы можете добавить его в свой проект JavaScript, выполнив в терминале следующую команду:
- npm install jsonwebtoken
И импортируйте его в свои файлы следующим образом:
const jwt = require('jsonwebtoken');
Чтобы подписать токен, вам нужно будет иметь 3 части информации:
- Секрет токена
- Фрагмент данных для хеширования в токене.
- Срок действия токена
секрет токена – это длинная случайная строка, используемая для шифрования и расшифровки данных.
Один из вариантов создания этого секрета — использовать встроенную в Node.js библиотеку crypto
, например:
> require('crypto').randomBytes(64).toString('hex')
// '09f26e402586e2faa8da4c98a35f1b20d6b033c6097befa8be3486a829587fe2f90a832bd3ff9d42710a4da095a2ce285b009f0c3730cd9b8e1af3eb84df6611'
Предупреждение: будьте осторожны! Если ваш секрет
прост, процесс проверки токена будет намного проще взломать неавторизованным злоумышленником.
Теперь сохраните этот секрет в файле .env
вашего проекта:
TOKEN_SECRET=09f26e402586e2faa8da4c98a35f1b20d6b033c60...
Чтобы перенести этот токен в файл Node.js и использовать его, вам нужно использовать dotenv
:
- 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, где вы найдете упражнения и проекты по программированию.