JWT (JSON Web Token) представляет собой компактный токен,
используемый для передачи утверждений (claims) между участниками системы
в виде JSON-структуры. В библиотеке Jsrsasign создание JWT реализуется
через механизм JWS (JSON Web Signature), где основная функция
формирования подписи и сборки токена —
KJUR.jws.JWS.sign.
JWT состоит из трёх частей:
Каждая часть кодируется в Base64URL и соединяется точками.
Перед формированием токена необходимо понимать, какие данные участвуют в подписи:
Header Содержит информацию о типе токена и алгоритме подписи:
{
"alg": "HS256",
"typ": "JWT"
}
Payload Содержит утверждения (claims):
{
"sub": "1234567890",
"name": "Ivan Ivanov",
"admin": true,
"iat": 1710000000
}
Основной метод формирования JWT:
KJUR.jws.JWS.sign(alg, header, payload, key)
Параметры:
alg — алгоритм подписи (HS256,
HS384, HS512, RS256 и др.)header — объект или JSON-строка заголовкаpayload — объект или JSON-строка полезной нагрузкиkey — секрет или приватный ключ (в зависимости от
алгоритма)Алгоритм HS256 использует общий секрет для подписи и проверки.
const header = {
alg: "HS256",
typ: "JWT"
};
const payload = {
sub: "user123",
name: "Ivan Ivanov",
role: "admin",
iat: Math.floor(Date.now() / 1000)
};
const secret = "super_secret_key";
const jwt = KJUR.jws.JWS.sign(
"HS256",
JSON.stringify(header),
JSON.stringify(payload),
secret
);
console.log(jwt);
При использовании HMAC:
Ассиметричный алгоритм RS256 использует пару ключей:
Приватный ключ должен быть в формате PEM.
const header = {
alg: "RS256",
typ: "JWT"
};
const payload = {
sub: "user456",
name: "Sergey Petrov",
role: "user",
iat: Math.floor(Date.now() / 1000)
};
const privateKey = `
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...
-----END PRIVATE KEY-----
`;
const jwt = KJUR.jws.JWS.sign(
"RS256",
JSON.stringify(header),
JSON.stringify(payload),
privateKey
);
console.log(jwt);
При использовании RSA:
Jsrsasign допускает передачу объектов напрямую:
const jwt = KJUR.jws.JWS.sign(
"HS256",
header,
payload,
secret
);
В этом случае библиотека автоматически сериализует структуру в JSON.
JWT часто содержит стандартные поля:
iss — издатель токенаsub — субъектaud — аудиторияexp — время истеченияiat — время выпускаПример с ограничением срока жизни:
const payload = {
sub: "user789",
iss: "auth-server",
exp: Math.floor(Date.now() / 1000) + 3600,
iat: Math.floor(Date.now() / 1000)
};
const jwt = KJUR.jws.JWS.sign(
"HS256",
{
alg: "HS256",
typ: "JWT"
},
{
sub: "user999",
exp: Math.floor(Date.now() / 1000) + 600,
iat: Math.floor(Date.now() / 1000)
},
"secret123"
);
Чаще всего используются:
Выбор алгоритма влияет на модель безопасности:
Внутри KJUR.jws.JWS.sign происходит:
header.payloadНеверный формат ключа RSA ключ должен быть в PEM-формате, включая заголовки:
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Несоответствие алгоритма Если указан
RS256, но передан симметричный ключ, подпись не будет
валидной.
Некорректный JSON Передача строки без корректной сериализации может привести к ошибкам подписи:
// потенциально проблемный вариант
payload: "{sub: user}"
Типичный процесс формирования JWT:
const header = { alg: "HS256", typ: "JWT" };
const payload = {
sub: "1001",
permissions: ["read", "write"],
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 3600
};
const token = KJUR.jws.JWS.sign(
"HS256",
JSON.stringify(header),
JSON.stringify(payload),
"my_secret_key"
);
Подпись обеспечивает:
Любое изменение payload после подписи делает токен недействительным при проверке.
Если изменить payload вручную:
Поля iat и exp должны использовать Unix
timestamp (секунды):
Math.floor(Date.now() / 1000)
Использование миллисекунд приводит к некорректной проверке срока действия.
Payload может содержать вложенные структуры:
const payload = {
user: {
id: 10,
name: "Alex"
},
roles: ["admin", "editor"],
session: {
device: "mobile",
ip: "127.0.0.1"
}
};
Jsrsasign корректно сериализует такие объекты перед подписью.
HS256:
RS256:
Минимально необходимый набор:
KJUR.jws.JWS.sign(
"HS256",
{ alg: "HS256", typ: "JWT" },
{ sub: "1" },
"key"
);