Как декодировать JWT-токен в JavaScript без использования библиотеки?
Вопрос: Как декодировать полезную нагрузку JWT с помощью JavaScript без использования библиотеки?
Я пытаюсь декодировать JWT (JSON Web Token), чтобы получить объект полезной нагрузки, который затем смогу использовать в своем фронтенд-приложении.
У меня есть токен формата: xxxxxxxxx.XXXXXXXX.xxxxxxxx
.
В результате я ожидаю получить следующий объект полезной нагрузки:
{exp: 10012016, name: 'john doe', scope: ['admin']}
Как правильно реализовать этот функционал на чистом JavaScript? Спасибо за помощь!
5 ответ(ов)
Примечание: данный код не проверяет подпись токена, он просто извлекает JSON содержимое из токена, которое могло быть подделано.
Браузер
Рабочая функция для парсинга JWT с поддержкой юникода:
function parseJwt(token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
}
JWT использует base64url
(RFC 4648 §5), поэтому использование только atob
(который работает с base64
) недостаточно.
Node.js
function parseJwt(token) {
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
}
Таким образом, эти функции позволяют вам извлекать полезные данные из JWT, но не забудьте о том, что они не проверяют подпись, и полученные данные могут быть поддельными.
Функция parseJwt
, которую вы представили, выполняет разбор (декодирование) JWT-токена (JSON Web Token). Она использует конструкцию try-catch
, чтобы обработать возможные ошибки при декодировании.
Вот как работает функция:
const parseJwt = (token) => {
try {
return JSON.parse(atob(token.split('.')[1])); // Разделяет токен, декодирует вторую часть и преобразует ее из JSON
} catch (e) {
return null; // В случае ошибки возвращает null
}
};
- Разделение токена: Токен состоит из трех частей, разделенных точками. Функция берет вторую часть (payload), которая содержит полезную нагрузку.
- Декодирование:
atob
используется для декодирования строки из Base64 в ASCII. - Парсинг:
JSON.parse
преобразует полученную строку в объект JavaScript. - Обработка ошибок: Если произошла ошибка (например, токен некорректен или содержит недопустимые данные), функция вернет
null
, что позволяет избежать сбоев в программе.
Эта реализация проста и удобна для разбора JWT, и использование try-catch
помогает безопасно обрабатывать ошибки. Если у вас есть дополнительные вопросы, не стесняйтесь обращаться!
Если вы хотите разобрать JWT (JSON Web Token) в Node.js, вы можете использовать следующий код:
function parseJwt(token) {
var base64Payload = token.split('.')[1];
var payload = Buffer.from(base64Payload, 'base64');
return JSON.parse(payload.toString());
}
let payload = parseJwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
console.log("payload:- ", payload);
Обратите внимание, что если вы используете Node.js, вам может понадобиться установить пакет buffer
, чтобы использовать класс Buffer
. Для этого выполните команду:
npm install buffer
И затем подключите его в своем коде:
var Buffer = require('buffer/').Buffer;
Этот код разбирает токен, извлекает полезную нагрузку из его второй части (после первого .
), декодирует ее из Base64 и затем преобразует в объект JavaScript для дальнейшей работы.
Если вы используете TypeScript или обычный JavaScript, вот простая функция без зависимостей, готовая для копирования и вставки в ваш проект (строится на основе ответа @Rajan Maharjan).
Этот ответ особенно хорош, не только потому что он не зависит от каких-либо npm-модулей, но и потому что он не использует никаких встроенных модулей Node.js (таких как Buffer
), как это делают некоторые другие решения, и, конечно же, не будет работать в браузере (если не использовать полифилы, но в этом нет смысла с самого начала). Кроме того, JSON.parse
может вызывать ошибки во время выполнения, и эта версия (особенно в TypeScript) заставит вас обработать их. Аннотации JSDoc сделают содержание вашего кода более понятным для будущих разработчиков. 😃
/**
* Возвращает представление JS объекта Javascript Web Token из его распространенной закодированной
* строковой формы.
*
* @template T ожидаемая структура парсенного токена
* @param {string} token Javascript Web Token в форме base64, разделенный `.`
* @returns {(T | undefined)} представление объекта токена
* или undefined, если парсинг не удался
*/
export function getParsedJwt<T extends object = { [k: string]: string | number }>(
token: string,
): T | undefined {
try {
return JSON.parse(atob(token.split('.')[1]))
} catch {
return undefined
}
}
Для полноты картины вот версия на чистом JavaScript:
/**
* Возвращает представление JS объекта Javascript Web Token из его распространенной закодированной
* строковой формы.
*
* @param {string} token Javascript Web Token в форме base64, разделенный `.`
* @returns {(object | undefined)} представление объекта токена
* или undefined, если парсинг не удался
*/
export function getParsedJwt(token) {
try {
return JSON.parse(atob(token.split('.')[1]))
} catch (error) {
return undefined
}
}
В среде Node.js объект "window" отсутствует, поэтому можно использовать следующий код:
let base64Url = token.split('.')[1]; // токен, который вы получаете
let base64 = base64Url.replace('-', '+').replace('_', '/');
let decodedData = JSON.parse(Buffer.from(base64, 'base64').toString('binary'));
Этот код отлично работает для меня. Надеюсь, это поможет!
Как перенаправить на другую веб-страницу?
Где найти документацию по форматированию даты в JavaScript?
Как определить нажатие клавиши Esc?
Как проверить, содержит ли массив строку в TypeScript?
Ссылка и выполнение внешнего JavaScript-файла, размещенного на GitHub