JSONWebToken
JSONWebToken - это библиотека для создания (подписания) и подтверждения (проверки) токенов, используемых для аутентификации/авторизации пользователей. Данная библиотека является реализацией JSON Web Tokens для
Node.js.
Установка
yarn add jsonwebtoken
# или
npm i jsonwebtoken
Подписание (создание) токена
const jwt = require('jsonwebtoken')
jwt.sign(payload, secretOrPrivateKey, [options, callback])
// Пример
jwt.sign({
username: 'John',
email: 'john@email.com'
},
'secret',
{
expiresIn: '1h'
}
)
Если передан колбек, то метод выполняется асинхронно. Данный колбек получает объект ошибки err. В противном случае, метод выполняется синхронно, возвращая токен в виде строки.
Аргументы
payload- полезная нагрузка: объект, буфер или строка, представляющие валидный JSON. Объект преобразуется с помощью методаJSON.stringify()secretOrPrivateKey- строка, буфер или объект, содержащие секрет для алгоритмов HMAC или зашифрованный с помощью схемы PEM приватный ключ для RSA и ECDSA
Настройки
-
algorithm(по умолчаниюHS256) -
expiresIn- время, в течение которого токен считается действительным: 100 - 100 с, '100' - 100 мс, '1h' - 1 час, '2d' - 2 дня -
notBefore- время, по истечении которого токен будет считаться действительным -
audience -
issuer -
jwtid -
subject -
noTimestamp -
header -
keyid -
mutatePayload- если имеет значениеtrue, функцияsign()будет модифицировать объектpayloadнапрямую. Это бывает полезным, когда нам нужна "сырая" ссылка на полезную нагрузку после применения к ней настроек, но до шифрования.
Настройки expiresIn, notBefore, audience, subject, issuer могут быть определены прямо в payload как exp, nbf, aud, sub и iss, соответственно.
Заголовок может быть кастомизирован через объект options.header.
В сгенерированный jwt по умолчанию включается iat (время выпуска, создания), если не определено noTimestamp: true.
Пример синхронного подписания токена с использованием RSA SHA256
const privateKey = fs.readFileSync('private.key')
const token = jwt.sign({ name: 'John Smith' }, privateKey, { algorithm: 'RS256' })
Пример асинхронного подписания токена
jwt.sign({ name: 'John Smith' }, privateKey, { algorithm: 'RS256' }, (err, token) => {
if (err) console.error(err)
console.log(token)
})
Подтверждение (проверка) токена
const jwt = required('jsonwebtoken')
jwt.verify(token, secretOrPublicKey, [options, callback])
Если передан колбек, то метод выполняется асинхронно. Данный колбек получает декодированную полезную нагрузку при условии валидной сигнатуры и опциональных настроек. В противном случае, выбрасывается исключение.
Без колбека метод выполняется синхронно, возвращая декодированный payload при условии валидной сигнатуры и опциональных настроек. В противном случае, выбрасывается исключение.
Аргументы
tokensecretOrPublicKey- еслиjwt.verify()вызывается асинхронно, данный аргумент может быть функцией, запрашивающей секрет или публичный ключ. Некоторые библиотеки в качестве секрета ожидают получить строку в формате base64. В этом случае вместоsecretследует передатьBuffer.from(secret, 'base64')
Настройки
algorithms- массив с названиями разрешенных алгоритмов (['HS256', 'HS384'])audiencecomplete- возвращает объект{ payload, header, signature }вместо содержимого полезной нагрузкиissuerjwtidignoreExpiration- еслиtrue, время жизни токена будет игнорироватьсяignoreNotBeforesubjectclockTolerance- допустимая разница во времени в секmaxAge- максимально допустимый "возраст" токена (100, '100', '1h', '2d')clockTimestamp- время в сек, используемое в качестве текущего для всех сравненийnonce- используется вOpen IDдля ID токенов
Примеры
// Синхронное подтверждение симметричного токена
try {
const decoded = jwt.verify(token, 'secret')
console.log(decoded.name) // John
} catch (err) {
console.error(err)
}
// или
jwt.verify(token, 'secret', (err, decoded) => {
if (err) console.error(err)
console.log(decoded.name) // John
})
// Подтверждение асимметричного токена
const cert = fs.readFileSync('public.pem') // получаем публичный ключ
jwt.verify(token, cert, (err, decoded) => {
if (err) console.error(err)
console.log(decoded.name) // John
})
// Подтверждение опциональных настроек
const cert = fs.readFileSync('public.pem') // получаем публичный ключ
jwt.verify(token, cert, { audience: 'urn:john', issuer: 'urn:issuer', jwtid: 'jwtid', subject: 'subject' }, (err, decoded) => {})
// Подтверждение с помощью колбека `getKey()`
const jwksClient = require('jwks-rsa')
const client = jwksClient({
jwksUri: 'https://example.com/.well-known/jwks.json'
})
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key.publicKey || key.rsaPublicKey
callback(null, signingKey)
})
}
jwt.verify(token, getKey, options, (err, decoded) => {
if (err) console.error(err)
console.log(decoded.name) // John
})
Расшифровка (декодирование) токена
jwt.decode(token, [options])
Метод является синхронным и возвращает расшифрованный токен без подтверждения валидности сигнатуры.
Настройки
json- принудительное применениеJSON.parse()кpayloadcomplete- возвращает объект{ payload, header }
Пример
const decoded = jwt.decode(token)
console.log(decoded.name) // John
Ошибки
TokenExpiredError- name
- message: 'jwt expired'
- expiredAt
JsonWebTokenError- name
- messages:
- 'invalid token'
- 'jwt malformed'
- 'jwt signature is required'
- 'invalid signature'
- 'jwt audience | issuer | id | subject invalid. expected: ...'
NotBeforeError- name
- message: 'jwt not active'
- date